三个文件
app.vue # 自定义的业务,调用自己封装的组件child.vue
child.vue # 自己封装的第三方组件plug.vue,便于上层调用
plug.vue # 第三方组件,提供v-model数据绑定
调用层次结构
app -> child -> plug
child在这里起到一个承上启下的桥梁功能
代码 app.vue
app.vue 父组件:{{value}}
父组件+1
import child from './Child.vue';
export default {
components:{
child
},
data(){
return {
value: 0
}
},
methods:{
changeValue(){
this.value++;
}
}
}
Child.vue
child.vue 子组件:{{value}}
子组件+1
import plug from "./Plug.vue";
export default {
props: ["value"],
components: {
plug
},
methods: {
changeValue() {
this.value++;
this.$emit('input', this.value)
}
}
};
Plug.vue
plug.vue 插件:{{value}}
export default {
props: ["value"]
};
修改app值
这样做可以实现 appchildplug 之间数据同步,不过会有一个警告
[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: "value"
原因是vue2中的数据只能单向流动,不能修改外层数据 child 组件中修改了value值
解决方案修改child.vue 的value为data属性, 警告消失
child.vue 子组件:{{value}}
子组件+1
import plug from "./Plug.vue";
export default {
props: ["value"],
components: {
plug
},
// 添加data属性
data(){
return {
innerVlaue: this.value
}
},
methods: {
changeValue() {
this.innerVlaue++;
this.$emit('input', this.innerVlaue)
}
}
};
遇到如下问题 1、修改app的值,可以传递到child,不能传递到plug 2、修改child的值,可以传递到child 和 app 3、修改plug插件的值,可以传递到child 和 app
修改child的 data 属性为computed 属性 此时app, child, plug数据都可以正常传递
child.vue 子组件:{{innerVlaue}}
子组件+1
import plug from "./Plug.vue";
export default {
props: ["value"],
computed: {
innerVlaue:{
get(){
return this.value
},
set(newValue){
this.$emit("input", newValue)
}
}
},
components: {
plug
},
methods: {
changeValue() {
this.innerVlaue++;
}
}
};
至此,子孙三代的数据传递正常,warn问题解决 自始至终,app, plug 的代码都没有做修改,只是修改了child 中的data属性或computed 所以,要正常通信,需要修改中间数据层的传递方式,既要考虑父级组件数据流入,也要兼顾子组件的事件传入
最后在child中使用 computed 计算属性完成了承上启下数据传递
v-model同样可以使用.sync实现,只是写法不一样
如果子组件不需要获取父组件数据,父组件直接可以和插件通信, 可以参看文章:
Vue基于 a t t r s 及 attrs及 attrs及listeners实现隔代通信