深入理解.sync用法

11,334 阅读1分钟

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