vue 父子组件通信详解
这是一篇详细讲解 vue 父子组件之间通信的文章,初始学习 vue 的时候,总是搞不清楚几个情况
- 通过 props 在父子组件传值时,v-bind:data="data",props 接收的到底是哪个?
- this.$emit 提交的事件名称,v-on:handleChange="handleChange",和父组件监听时候创建的方法名是否一样?到底哪个才是 v-on 应该监听的事件名称?
你是否也有这样的疑惑呢?如果你跟我有一样的疑惑,那么继续往下看吧 ~~
1. 创建一个父组件 Parent.vue,在 data 中添加一个 parentAge
<template> <div class="my-parent"> <h3> 我是父组件 </h3> <p> 父组件的年龄是:{parentAge}}</p> </div> </template><script>
export default {
data() {
return {
parentAge: 50
};
}
};
</script><style>
.my-parent {
text-align: left;
text-indent: 1em;
width: 1000px;
height: 500px;
border: 1px solid #555;
}
</style>
2. 创建子组件,在 data 中添加一个 childAge
<template> <div class="my-child"> <h3> 我是子组件 </h3> <p> 子组件的年龄是:{{childAge}}</p> </div> </template><script>
export default {
data() {
return {
childAge: 27
};
}
};
</script><style>
.my-child {
margin: 20px;
width: 760px;
height: 200px;
border: 1px solid red;
}
</style>
3. 把父子组件关联起来,并通过 v-bind(即简写“:”)将父组件中的 parentAge 值,传递给子组件
v-on 绑定的属性名称 deliverParentAge 与 data 中定义的 parentAge 名称可以不一样
属性 deliverParentAge 通过 v-bind 绑定的,也是子组件中通过 props 接收的,而parentAge 是要传递给子组件的数值,它是一个值
<template> <div class="my-parent"> <h3> 我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3> <h3> 我要通过 v-bind( 即简写":") 语法糖绑定一个属性 deliverParentAge,将父组件的值传递到子组件中 </h3> <!-- 下面就是我的子组件 --> <my-child :deliverParentAge="parentAge"></my-child></div>
</template><script>
import MyChild from "./Child";
export default {
components: {MyChild},
data() {
return {
parentAge: 49
};
}
};
</script>
4. 子组件通过 props 属性,在子组件中接收父组件传过来的值
<template> <div class="my-child"> <h5> 我是子组件,我可以通过属性 props 来接收父组件传过来的年龄值是:{{deliverParentAge}}</h5> </div> </template><script>
export default {
data() {
return {
childAge: 27
};
},
props: {
deliverParentAge: Number
}
};
</script>
5. 现在来修改父组件的值(这个不是真的修改而是通过 this.$emit 提交一个事件,将子组件的行为告诉父组件)
<template> <div class="my-child"> <h5> 我是子组件,我可以通过属性 props 来接收父组件传过来的年龄值是:{{deliverParentAge}},这是一个数字类型 </h5> <h5> 并且,我要告诉他,他今年生日已经过了,所以他的年龄应该 <button @click="AddAge"> 加 1</button></h5> 下面我要通过this.$emit 方法提交一个事件 addParentAge,告诉我的父组件,他的实际年龄 </div> </template><script>
export default {
data() {
return {
childAge: 27
};
},
props: {
deliverParentAge: Number
},
// 新建一个计算属性,将父组件原来的值加 1
computed: {
parentActualAge() {
return this.deliverParentAge + 1;
}
},
methods: {
AddAge() {
this.$emit("addParentAge", this.parentActualAge);
}
}
};
</script>
6. 父组件通过语法糖 v-on(即简写为“@”)来监听子组件提交的事件addParentAge
this.$emit 提交的事件名称 addParentAge,与方法handleAddParentAge 名称可以不一样
addParentAge 是子组件提交的事件名称,也是父组件通过 v-on 监听的事件名称,而handleAddParentAge 是父组件自定义的方法名称
<template> <div class="my-parent"> <h3> 我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3> <h3> 我要通过 v-bind( 即简写":")语法糖绑定一个属性 parentAge,告诉子组件我的年龄值是:{{parentAge}}</h3> <!-- 下面就是我的子组件 --> <my-child :deliverParentAge="parentAge" @addParentAge="handleAddParentAge"></my-child> <h3> 通过监听子组件提交的事件 addParentAge,我知道到了自己的实际年龄应该是:{{parentAge+1}},并通过方法 handleAddParentAge,在控制台打印出我的真实年龄 </h3></div>
</template><script>
import MyChild from "./Child";
export default {
components: {MyChild},
data() {
return {
parentAge: 49
};
},
methods: {
handleAddParentAge(actualAge) {
console.log("父组件的实际年龄是:", actualAge);
}
}
};
</script>
现在来看控制台打印出来的内容
7. 现在将子组件 data 中的值,提交给父组件来看看
<template> <div class="my-child"> <h5> 我是子组件,我可以通过属性 props 来接收父组件传过来的年龄值是:{{deliverParentAge}},这是一个数字类型 </h5> <h5> 现在我要告诉父组件,我的年龄是 {{childAge}}, 这样他就可以知道,我们 <button @click="DiffAge"> 相差 </button> 多少岁 </h5> <h5> 并且,我要告诉他,他今年生日已经过了,所以他的年龄应该 <button @click="AddAge"> 加 1</button></h5> 下面我要通过 this.$emit 方法提交一个事件 addParentAge,告诉我的父组件,他的实际年龄 </div> </template><script>
export default {
data() {
return {
childAge: 27
};
},
props: {
deliverParentAge: Number
},
computed: {
parentActualAge() {
return this.deliverParentAge + 1;
}
},
methods: {
AddAge() {
this.$emit("addParentAge", this.parentActualAge);
},
DiffAge() {
this.$emit("differAge", this.childAge);
}
}
};
</script>
8. 父组件通过 v-on 监听子组件提交的事件differAge
<template> <div class="my-parent"> <h3> 我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3> <h3> 我要通过 v-bind( 即简写":")语法糖绑定一个属性 parentAge,告诉子组件我的年龄值是:{{parentAge}}</h3> <!-- 下面就是我的子组件 --> <my-child :deliverParentAge="parentAge" @differAge="handleDifferAge" @addParentAge="handleAddParentAge"></my-child> <h3> 通过监听子组件提交的事件 addParentAge,我知道到了自己的实际年龄应该是:{{parentAge+1}},并通过方法 handleAddParentAge,在控制台打印出我的真实年龄 </h3> <h3> 通过监听子组件提交的事件 differAge,并通过方法 handleDifferAge,在控制台打印出子组件的年龄 </h3></div>
</template><script>
import MyChild from "./Child";
export default {
components: {MyChild},
data() {
return {
parentAge: 49
};
},
methods: {
handleAddParentAge(actualAge) {
console.log("父组件的实际年龄是:", actualAge);
},
handleDifferAge(child) {
console.log("我们的年龄差是:", this.parentAge + 1 - child);
}
}
};
</script>
现在来看看页面展示的效果和控制台打印出来的信息
下面贴上完整的代码
// Parent.vue <template> <div class="my-parent"> <h3> 我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3> <h3> 我要通过 v-bind( 即简写":")语法糖绑定一个属性 parentAge,告诉子组件我的年龄值是:{{parentAge}}</h3> <!-- 下面就是我的子组件 --> <my-child :deliverParentAge="parentAge" @differAge="handleDifferAge" @addParentAge="handleAddParentAge"></my-child> <h3> 通过监听子组件提交的事件 addParentAge,我知道到了自己的实际年龄应该是:{{parentAge+1}},并通过方法 handleAddParentAge,在控制台打印出我的真实年龄 </h3> <h3> 通过监听子组件提交的事件 differAge,并通过方法 handleDifferAge,在控制台打印出子组件的年龄 </h3></div>
</template><script>
import MyChild from "./Child";
export default {
components: {MyChild},
data() {
return {
parentAge: 49
};
},
methods: {
handleAddParentAge(actualAge) {
console.log("父组件的实际年龄是:", actualAge);
},
handleDifferAge(child) {
console.log("我们的年龄差是:", this.parentAge + 1 - child);
}
}
};
</script><style lang="stylus" scoped>
.my-parent {
text-align: left;
text-indent: 1em;
width: 1000px;
height: 500px;
border: 1px solid #555;
}
</style>
// Child.vue <template> <div class="my-child"> <h5> 我是子组件,我可以通过属性 props 来接收父组件传过来的年龄值是:{{deliverParentAge}},这是一个数字类型 </h5> <h5> 现在我要告诉父组件,我的年龄是 {{childAge}}, 这样他就可以知道,我们 <button @click="DiffAge"> 相差 </button> 多少岁 </h5> <h5> 并且,我要告诉他,他今年生日已经过了,所以他的年龄应该 <button @click="AddAge"> 加 1</button></h5> 下面我要通过 this.$emit 方法提交一个事件 addParentAge,告诉我的父组件,他的实际年龄 </div> </template><script>
export default {
data() {
return {
childAge: 27
};
},
props: {
deliverParentAge: Number
},
computed: {
parentActualAge() {
return this.deliverParentAge + 1;
}
},
methods: {
AddAge() {
this.$emit("addParentAge", this.parentActualAge);
},
DiffAge() {
this.$emit("differAge", this.childAge);
}
}
};
</script><style>
.my-child {
margin: 20px;
width: 760px;
height: 200px;
border: 1px solid red;
}
</style>
希望对你有用,欢迎提问与指正,一起学习前端呀!