使用之前
在讲解这个语法糖之前,我们有必要先了解 Vue 中组件之间单向数据流。
通信规则:
Vue 提单向数据流,即父级 props 的更新会流向子组件,但是反过来则不行。这是为了防止意外的改变父组件状态,使得应用的数据流变得难以理解。如果破坏了单向数据流,当应用复杂时,debug 的成本会非常高。
所以开发中,我们需要遵循:父组件可以修改子组件的内容,而子组件是不能(不推荐)直接改变父组件的内容,但子组件可以通过事件触发的方式通知父组件来修改自己本身的内容。
Vue规则
在Vue的父子组件触发事件通信的过程中,有以下几条规则:
- 组件不能修改
props传入的外部数据。 - 组件可以通过
this.$emit触发事件并传参。 $event可以获取$emit的参数。
.sync的用法
.sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值
代码举例:
child.vue(子组件)
<template>
<div class="child">
{{money}}
//事件监听,点击按钮触发$emit,更新money数据 -100
<button @click="$emit('update:money', money-100)"> //因为money是外部数据,不可以直接改动即不可以直接改动props
//语法是"$emit('update:props',newValue)"
<span>花钱</span>
</button>
</div>
</template>
<script>
export default {
props: ["money"] //接受一个名为money的外部数据
};
</script>
<style>
.child {
border: 3px solid green;
}
</style>
parent.vue(父组件)
<template>
<div class="app">
App.vue 我现在有 {{total}}
<hr>
<!-- 语法糖式写法 -->
<!-- <Child :money.sync="total"/> -->
<Child :money="total" v-on:update:money="total = $event"/> //因为total是个变量,所以前面记得要加冒号
<!--Child :money="total"这一部分意为把"total"这个变量传给Child这个子组件,上面的整行代码可改为<Child :money.sync="total"/> 语法为 子组件的命名 :props.sycn=value -->
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
data() {
return { total: 10000 }; //这里的total就是上面的注释所指的value
},
components: { Child: Child }
};
</script>
<style>
.app {
border: 3px solid red;
padding: 10px;
}
</style>
这个代码就是上述内容的解释,实现的原理是利用eventBus,在子组件使用$emit('update:money', money-100) 来通知父组件去响应,而父组件则通过$event 来接收经过子组件修改后的值。
<Child :money="total" v-on:update:money="total = $event"/>
这么长的语句可以缩写为:
<Child :money.sync="total"/>
而子组件内也必须用'update:money'事件名去触发响应
<button @click="$emit('update:money', money-100)">