之前写的Vue基础知识合集中已经包含了传值的知识点,但是由于内容太多,所以我把这个面试中的重要问题单独拿出来,进行详细解释,如果想看Vue基础知识合集可以访问 juejin.cn/post/684490… 这篇博客
父传子
条件:
父组件中数据已知,子组件数据未知,子组件想要使用父组件的值,
可以通过属性绑定的方式将父组件的值传递给子组件使用
- 在父组件中,以标签形式使用子组件的时候,可以通过属性绑定,为子组件传递数据: 父组件中需要书写的:
<my-son :pmsg1="parentMsg" :pinfo="parentInfo"></my-son>
....
data(){
return {
parentMsg:'我是父组件' ,
parentInfo:'我是父组件的信息'
}
}
2.在子组件中,如果向用父组件传递过来的数据,必须先定义 props 数组来接收:
<script>
export default {
data(){
return {}
},
methods: {},
// property 属性
// 注意:父组件传递到子组件中的数据,必须经过 props 的接收,才能使用;
// 通过 props 接收的数据,直接可以在页面上使用;注意:不接受,不能使用外界传递过来的数据
props: ['pmsg1', 'pinfo']
}
</script>
注意:
这里的prop是只读属性,可以传递数组也可以传递对象,如果是传递对象形式的:
props: {
// 检测类型
height: Number,
// 检测类型 + 其他验证
age: {
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
这里面也可以有一些其他的参数,比如说是数据类型,或者是验证方法等都可以,父组件传递给子组件的成员数据props都是可读数据,不要为他们重新赋值,
但是data数据都是当前属性的私有数据,而且data中的数据都是可读可写的
由于props中的数据都是只读的,所以如果想为props数据重新复制,可以把数据转存到data中,从而实现重新赋值,
具体操作:
import _ from 'lodash';
export default {
data(){
// 对于转存修改属性只是简单数据类型可以转,对于复杂数据类型还需要另外进行操作
return {
infoFromParent:this.pinfo,
msgFromParent:_.cloneDeep(this.pmsg)
}
},
// 子组件需要使用props按钮,接收外界传递过来的数据
props:['pmsg','pinfo']
由于上述进行值的传递和转存的时候,都是简单的数据类型的值,所以如果变成是引用数据类型的值,就会出现值会同时修改的情况,所以这里需要进行深拷贝操作,这里进行深拷贝操作的是利用一个包lodash
}
3.接收完的props数据,可以直接在子组件的 template 区域中使用:
<template>
<div>
<h3>这是子组件 --- {{pmsg1}} --- {{pinfo}}</h3>
</div>
</template>
具体的运行看下图所示:

子传父
条件: 子组件数据已知,父组件数据未知,父组件想要使用子组件的方法,这时就需要子传父
- 如果父向子传递方法,需要使用 事件绑定机制:
<my-son @func="show"></my-son>
...
methods:{
//这个methods方法需要在父组件中定义这个方法:
show(val){
//这个val是一个形参,真正的参数,是在调用的时候传过来的参数
console.log(val)
}
}
注意:这里只是在父组件中定义了这个方法,真正的调用还是在子组件中调用这个方法,传参也是由子组件来进行传参
子组件调用方法:
methods: {
// 点击子组件中的按钮,触发按钮的点击事件
btnHandle(){
// 在子组件中通过this.$emit()方法,触发父组件,为子组件绑定func事件
this.$emit('func' +this.msg)
//this.msg才是真正的实参,传的值也是this.msg
}
},
子传父的具体步骤:
1.子向父传值,要使用 事件绑定机制@;
2.父向子传递一个方法的引用
3.子组件中,可以使用 this.$emit() 来调用父组件传递过来的方法
4.在使用this.$emit()调用 父组件中方法的时候,可以从第二个位置开始传递参数;把子组件中的数据,通过实参,传递到父组件的方法作用域中;
5.父组件就可以通过形参,接收子组件传递过来的数据;
兄弟之间的传值
兄弟组件之间,实现传值,用到的技术,是 EventBus(第三方)
1.定义模块 bus.js
import Vue from 'vue'
export default new Vue()
2.在需要接收数据的兄弟组件中,导入 bus.js 模块
import bus from './bus.js'
- 在需要接收数据的兄弟组件中的 created 生命周期函数里, 使用 bus.$on('事件名称', (接收的数据) => {}) 自定义事件:
created(){
// 定义事件
bus.$on('ooo', (data)=>{
console.log(data)
})
}
4.在需要发送数据的兄弟组件中,导入 bus.js 模块
import bus from './bus.js'
5.在需要发送数据的兄弟组件中,使用 bus.$emit('事件名称', 要发送的数据) 来向外发送数据:
import bus from './bus.js'
export default {
data(){
return {
msg: 'abcd'
}
},
methods: {
sendMsg(){
// 触发 绑定的 事件,并向外传递参数
bus.$emit('ooo', this.msg)
}
}
}
注意:
我们发现在子传父和兄弟之间的传值都用到了$emit这个方法,所以我们可以得出一个结论,
就是在发送数据的时候都用的是函数传参的形式,调用$emit()方法进行参数的传递,此时值也传递出来了
我们在项目开发过程中,如果数据简单,就用到这中简单的传值,如果如果复杂就需要专门使用Vuex状态管理来进行数据间的传值,使用Vuex进行状态管理的博客可以参考: