按照我个人理解的话,开门见山的给大家总结一下,以便于大家看接下来的文章理解的更深一点,
大家都知道v-model可以让数据变成响应式,但是组件之间的传值是没有响应式这个说法的,因为Vue遵循单项数据流的原则,父组件传递给子组件中的值,是不支持修改的(只是不支持修改,要修改的话还是有方法的),所以.sync修饰符可以说是组件之间数据响应式的"v-model"
vue的子组件不能直接使用父组件的数据,所以我们需要用到prop传递数据,但是,子组件能不能直接修改父组件的数据呢?
按照官方文档的示例:监听子组件事件 我们得知vue通过自定义事件系统来帮助我们修改父组件上的数据。
它有一个api:$emit
,通过它我们可以在子组件上面修改父组件上面的数据。
- 在子组件上触发一个自定义事件,并传递一个自定义事件 写法:
@click="$emit('something')"
- 在父组件的子组件器上使用v-on监听这个自定义事件 写法:
<child :num='num' v-on:something='num += 1' /> //这个num是父组件上面的数据 先
通过以上方式可以让子组件修改父组件上的数据。
我们先分析一下$emit
这个api
$emit
$emit 共接收两个参数 参数:
{string} eventName 触发当前实例上的事件。
[...args] 附加参数都会传给监听器回调。
我们需要在子组件的template
上调用$emit
,然后在父组件上监听这个自定义事件,当执行时附加参数会传递到父组件上使用。
用法
...
props: ['msg'],
// 子组件上的写法 点击后触发一个"update:n"的事件,并把传过来的n -1当成args传递给监听器回调
<button @click="$emit('update:n',n-1)">子组件点击{{n}}
</button>
// 父组件上的写法,使用v-on监听update:n事件,并把传过来的$event赋值给n。
// $event就是子组件上的n-1
<child :n='msg' v-on:update:n="n=$event"></child>
示例代码
Vue.component('child', {
props: ['msg'],
template: `
<div>
<hr>
我是子组件
<button @click="$emit('update:n',msg-1)">子组件点击{{msg}}</button>
</div>
`
})new Vue({
el: '.app1',
data() {
return {
n: 100
}
},
template: `
<div>
父组件n:{{n}}
<child :msg='n'v-on:update:n='n=$event'></child>
</div>`
})
.sync 用法
上面的代码一共进行了两个步骤:
1、父组件上的字组件监听自定义事件并让property值n等于传递过来的$event
v-on:update:n='n=$event'
2、子组件内的代码点击后触发自定义事件并传递一个参数,参数为msg-1
@click="$emit('update:n',msg-1)"
那么,我们可以不可以简化代码呢?
vue很贴心地为我们做了相关工作,那就是.sync
修饰符
使用方法:
在父组件上告诉子组件传递过去的msg跟父组件上的n保持同步,相当于允许它修改
<child :msg.sync='n'></child>
复制代码
在子组件上的代码写为:
<button @click="$emit('update:msg',msg-1)">子组件点击{{msg}}</button>
复制代码
使用.sync
后写法需要注意的是:eventName只能采用update:传递过来的prop属性
的方式才行。