Vue组件传值(父传子,子传父,兄弟传值)

7,597 阅读4分钟

之前写的Vue基础知识合集中已经包含了传值的知识点,但是由于内容太多,所以我把这个面试中的重要问题单独拿出来,进行详细解释,如果想看Vue基础知识合集可以访问 juejin.cn/post/684490… 这篇博客

父传子

条件:

父组件中数据已知,子组件数据未知,子组件想要使用父组件的值,
可以通过属性绑定的方式将父组件的值传递给子组件使用
  1. 在父组件中,以标签形式使用子组件的时候,可以通过属性绑定,为子组件传递数据: 父组件中需要书写的:
<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>

具体的运行看下图所示:

子传父

条件: 子组件数据已知,父组件数据未知,父组件想要使用子组件的方法,这时就需要子传父

  1. 如果父向子传递方法,需要使用 事件绑定机制:
 <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'
  1. 在需要接收数据的兄弟组件中的 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进行状态管理的博客可以参考:

juejin.cn/post/684490…