在有些情况下,我们可能需要对一个 prop
进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。
这也是为什么我们推荐以 update:my-prop-name
的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:
this.$emit('update:title', newTitle)
然后父组件可以监听那个事件并根据需要更新一个本地的数据属性。例如:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
为了方便起见,我们为这种模式提供一个缩写,即 .sync
修饰符:
<text-document v-bind:title.sync="doc.title"></text-document>
当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用:
<text-document v-bind.sync="doc"></text-document>
需要进行双向绑定时,子组件使用computed
属性,实现set
,get
方法,get
方法返回父组件prop的传值,set
方法使用emit
传递事件变化。当然也可以通过watch.
假如我们需要封装一个组件 custom_dialog
,该组件内部封装了elementUI
的dialog
,我们需要传递一个名称为visible
的prop
,实现在父层调用该custom_dialog
组件时实现对visible
属性的双向绑定:
// custom_dialog.vue
<template>
<div>
<el-dialog :visible.sync="innervisible">
</el-dialog>
</div>
</template>
props:['visible'],
computed:{
innervisible:
{
get(){
return this.visible
},
set(val)
{
this.$emit('update:visible',val)
}
}
}
//--父组件
<template>
<div>
<custom-dialog :visible.sync="parentvisible">
</custom-dialog>
</div>
data() {
return {
parentvisible:false
}
},
</template>
当我们在外层改变prop visible
的值时(假定由false
改为true
,表现是弹窗被打开),根据数据流,可以反馈给子组件,子组件调用innervisible
的get
方法获取最新的visible
的值,弹窗被打开。
当子组件自身状态改变的情况呢?用过elementui
的同学应该知道,dialog
自带关闭按钮。点击关闭之后,由于双向绑定,需要修改到innervisible
的值为false,这时候由于vue数据流不能由子流向父,所以我们只能通过emit
的方式
this.$emit('update:visible',val)
这时候,父组件改变自己的控制值parentvisible
从而实现双向绑定。
2022.6.3日(长期有效):打个广告,苏州华为终端BG面向社会招聘人才,Java /C C++ / Python / Javascript 。有兴趣来苏州的同学们 可以加我V 15850277051 ,走内推流程,有问必答!