常见的场景:
在一个vue组件A中,使用另外一个组件B。A将自己的数据通过B组件的Props属性(propX)传递到B组件实例内部,B组件内部会修改该Props属性(propX)的值,此时在A组件内部的数值是否会收到影响呢?如下:
<template> ............ <el-dialog title="XXXX" :visible="show"> ............... </el-dialog> ............. </template> <script> export default { name: "A", data() { return { show:true }; }, methods:{ ............ } }
上面的组件A中使用了 el-dialog,并绑定了 el-dialog 的 visible值为show。在程序运行起来后 el-dialog 默认弹出,手动关闭 el-dialog 此时在组件A中show的值会是什么呢?仍然是true,并不是false。
造成这种问题的原因就是 el-dialog 内部 对 visible 属性的修该,并不能同步回到父组件A中的show。要解决上面的 el-dialog 不能同步回 visible 变化的问题很简单:
<el-dialog title="XXXX" :visible.sync="show"> ............... </el-dialog>
这样 el-dialog 对 visible 的修改就能同步到父组件A的show上。
问题完美解决了,那到底是如何解决的呢?不如打开 el-dialog 的源码学习一下:
hide(cancel) { if (cancel !== false) { this.$emit('update:visible', false); this.$emit('close'); this.closed = true; } }
实际上是在关闭时调用hide函数通过this.$emit('update:visible', false)来更新 visible 的值。
既然如此,我们自定义的组件也可以如法炮制,使其Props属性支持sync
子组件:
<template> <div> <button @click="click">点我</button> </div> </template> <script> export default { name:"cx", props:{ propx:{ type:Boolean, default:false } }, data(){ return { } }, methods:{ click(){ this.$emit("update:propx",false) } } } </script>
父组件:
<template> <div id="app"> <cx :propx.sync="v"></cx> </div> </template> <script> import cx from './packages/cx' export default { name: 'app', components:{ "cx":cx }, data () { return { v:true } }, methods:{ } } </script>
效果:
点击后: