场景
有时候我们需要给prop进行“双向绑定”,即父组件传给子组件的数据,子组件需要修改。但是在子组件直接修改会造成很多问题,比如无法得知变更来源。那么只能通过自定义事件通知父组件进行修改。
父组件
<template>
<div>
<Son :sonTitle="message" @update:sonTitle="changeTitle"></Son>
</div>
</template>
<script>
import Son from './components/Son.vue'
export default {
name: 'App',
components: {
Son
},
data() {
return {
message: '标题'
}
},
methods: {
changeTitle($event) {
this.message = $event
}
}
}
</script>
子组件
<template>
<div>
<span>{{ sonTitle }}</span>
<button @click="changeTitle">更改标题</button>
</div>
</template>
<script>
export default {
name: "Son",
props: {
sonTitle: {
type: String,
default: ''
}
},
methods: {
changeTitle() {
this.$emit('update:sonTitle', '新标题')
}
}
}
</script>
通过上面两段代码可以看到修改数据非常繁琐,需要子组件发送自定义事件,然后父组件监听事件从而进行修改。
.sync修饰符
父组件
<template>
<div>
<Son :sonTitle.sync="message"></Son>
</div>
</template>
<script>
import Son from './components/Son.vue'
export default {
name: 'App',
components: {
Son
},
data() {
return {
message: '标题'
}
}
}
</script>
子组件
<template>
<div>
<span>{{ sonTitle }}</span>
<button @click="changeTitle">更改标题</button>
</div>
</template>
<script>
export default {
name: "Son",
props: {
sonTitle: {
type: String,
default: ''
}
},
methods: {
changeTitle() {
this.$emit('update:sonTitle', '新标题')
}
}
}
</script>
可以看到子组件依旧发送自定义事件,但是父组件只需要v-bind绑定属性的时候使用.sync修饰符就可以实现数据更新。下面具体分析一下代码:
代码分析
- 子组件
- 根据官方文档,想要使用sync,那么子组件的自定义事件名是有要求的。格式为:
update:myPropName
。
- 父组件
- 在v-bind时添加sync修饰符即可。
- 该修饰符的等同于
@update:sonTitle="val => message = val"
。即对绑定的属性进行update监听,同时把$event的值给动态绑定的值(message)。
总结
.sync修饰符就是对prop进行双向绑定的一个语法糖。节省了父组件编写监听和对应的更新函数。