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属性的方式才行。