父子组件双向传值
- vue是单向数据流机制
- v-mode在组件中的双向传值的原理等同于触发了input事件
<input type="text" @input="handleInput" />
handleInput(e) {
console.log(e.target.value);
this.msg = e.target.value;
},
- 默认input事件触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
Vue.component("ComponentA", {
// 可以不写,相当于input标签中的value
props: {
value: "",
},
methods: {
handleClick() {
this.count++;
this.$emit("input", this.count);
},
},
data() {
return {
count: 0,
};
},
template: `<div>ComponentA
{{count}}
<button @click="handleClick">click</button>
</div>`,
});
app = new Vue({
el: `#app`,
template: `
<div>{{msg}}
{{count}}
<ComponentA v-model="count"></ComponentA>
</div>`,
data: {
msg: "hello world",
count: 0,
},
});
</script>
</body>
</html>
- 上边代码中,是将子组件的中count改变的值通过触发input事件发送出去的,这样就巧妙地实现了父子组件双向传值。但是需要注意的是,在子组件中触发input事件时发送什么样的数据,那么父组件中v-model绑定值的就会被覆盖。
Vue.component("ComponentA", {
props: {
value: "",
},
methods: {
handleClick() {
this.newCount[0].test++;
this.$emit("input", this.newCount);
},
},
data() {
return {
newCount: [{
tab: 0,
test: 1
}]
};
},
template: `<div>
子组件中的newCount:{{newCount}}
<p>来自父组件中的value:{{value}}</p>
<button @click="handleClick">子组件按钮</button>
</div>`,
});
app = new Vue({
el: `#app`,
template: `
<div>父组件的count:{{count}}
<ComponentA v-model="count"></ComponentA>
</div>`,
data: {
count: 0,
},
});
如果
this.$emit("input", this.count);
写的不是input,那么不会双向同步。当然也可以自定义触发事件,看下边
- 话不多说,来上帝视角
<div id="app"></div>
<script>
Vue.component("ComponentA", {
model:{
prop: "cxr",
event:"change",
},
props: {
cxr: "",
value: "",
},
methods: {
handleClick() {
this.count++;
this.$emit("change",this.count);
},
},
data() {
return {
count: 0,
};
},
template: `<div>ComponentA
<p>子组件{{count}}</p>
<button @click="handleClick">click</button>
</div>`,
});
app = new Vue({
el: `#app`,
template: `
<div>{{msg}}
<p>父组件{{count}}</p>
<ComponentA v-model="count"></ComponentA>
</div>`,
data: {
msg: "hello world",
count:0,
},
});