【JS】[vue] 理解.sync

考虑以下两个父子组件:

// 父组件

{

template: `

<div>

<p>I'm parent</p>

<p>parentCount: {{parentCount}}</p>

<child v-bind:childCount="parentCount"></child>

</div>

`,

data() {

return {

parentCount: 1

}

},

}

// 子组件

{

template:

`<div>

<p>I'm child</p>

<p>childCount: {{childCount}}</p>

<button @click="handleClickAdd">add in child</button>

</div>`,

props: ['childCount'],

}

父组件将值parentCount作为propchildCount传给子组件,我们希望点击子组件中按钮,使得父组件中的parentCount和子组件中的childCount都+1,我们想当然地这么写:

  // 子组件

methods: {

handleClickAdd() {

// 只需在子组件中对childCount+1,作为数据源,parentCount也会+1

this.childCount += 1

}

}

尝试点击按钮,会发现父组件的数据没有变化:

【JS】[vue] 理解.sync

同时控制台警告:

vue.js:634 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "childCount"

found in

---> <Child>

<Root>

这就是所谓的单向数据流

想当然的办法果然行不通。换个思路:既然prop的流动是单向的,我们可以在子组件中抛出事件,来通知父组件更新parentCount,这样childCount自然也更新了。别忘了,事件名不存在任何自动化的大小写转换,因此我们可以抛出叫做update:childCount的事件——父组件,你传进来的propchildCount更新了!父组件侦听到该事件后,把更新后的值赋给prop对应的数据源parentCount就行了:

  // 子组件

methods: {

handleClickAdd() {

this.$emit('update:childCount', this.childCount + 1)

}

}

// 父组件

`

<child

v-bind:childCount="parentCount"

v-on:update:childCount="parentCount=$event">

</child>

`

现在的代码就满足我们的需求了:

【JS】[vue] 理解.sync

我们回过头来看,父组件这么写多少有些笨重——差不多把childCount=parentCount写了两遍。因此,vue提供了.sync缩写:绑定prop时加上.sync,vue就会自动为我们设置叫做update:propName的更新事件。因此,上面的父组件代码完全等价于:

`

<child

v-bind:childCount.sync="parentCount">

</child>

`

有兴趣的话,还可以到源码里确认一下:
【JS】[vue] 理解.sync

以上是 【JS】[vue] 理解.sync 的全部内容, 来源链接: utcz.com/a/94205.html

回到顶部