在有些情况下,我们可能需要对一个 prop 进行 “双向绑定” 。要想实现父子组件的 “双向绑定” ,有如下几种办法。
第一种方式:
我们可以这么做,考虑如下代码
父组件:
<template>
<div class="app">
-------------- 父 -------------- <br>
<input type="text" v-model="doc.title">
{{ doc.title }}
<text-document :title="doc.title" @updatetitle="doc.title = $event"></text-document>
</div>
</template>
<script>
import child from "../components/child";
export default {
data () {
return {
doc: {
title: 'hello world'
}
}
},
components: {
'text-document': child,
},
}
</script>
子组件:
<template>
<div>
-------------- 子 -------------- <br>
<input @input="sendMsg" :value="title" />
{{ title }}
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: ['title'],
computed: {},
data () {
return {}
},
methods: {
sendMsg (event) {
this.$emit('updatetitle', event.target.value)
}
}
}
</script>
自行复制代码,查看运行结果:
我们在父组件的 input 框内随意输入字符,子组件的显示区域和 input 框中能够立马回显父组件中的数据。在子组件的 input 框内随意输入字符,亦然。
Tips: 有同学可能会问,代码中的 doc.title = $event
是什么意思?我在这里解释一下:
其实 doc.title = $event
只是一个简写,这里的原始写法为: (data) => doc.title = data
。如果连这都还看不懂的同学,我建议先去看看 $emit 的用法。
然后,($event) => doc.title = $event
可以简写成 doc.title = $event
。
注意,不能简写成 doc.title = data
,因为在事件中,$event
作为一个特殊符号,代表事件是能够被直接识别的,data 只是一个普通字符,不能被识别。
接下来,我们换一种方式,注意对比简单的代码变化细节。
第二种方式:
父组件修改项:
<text-document :title="doc.title" @update:title="doc.title = $event"></text-document>
子组件修改项:
this.$emit('update:title', event.target.value)
对,我们分别只修改了父子组件的各一行代码。将原来的 updatetitle
变为了 update:title
。至此,代码运行没有问题。
第三种方式:
第三种方式,我们只需要对父组件的一行代码进行修改。
父组件修改项:
<text-document :title.sync="doc.title"></text-document>
注意,至此我们使用到了 .sync
修饰符。现在,我们再回顾一下修改前的父组件代码,然后对两者进行对比。
<text-document :title="doc.title" @update:title="doc.title = $event"></text-document>
对比修改前的代码,我们发现:
之前代码中的 :title=doc.title
与 @update:title="doc.title = $event"
都不见了,取而代之的是 :title.sync="doc.title
。
这说明,.sync
修饰符在这里承载了两个功能:
-
.sync
将 title 作为 props 传给了子组件,title 接收 父组件 doc.title 的值 -
.sync
接收了子组件 $emit 触发的变化,并将相应的变化赋值给了父组件的 doc.title
注意到了吗?:title.sync="doc.title"
只是:title="doc.title" @update:title="doc.title = $event"
的一个语法糖而已。
就这样,名为 title 的 props 就在 父子组件 中实现了双向绑定。