总述:
        vue组件间通讯有什么方法:
             1) 使用props、$emit 传值 (prop向下传递,事件向上传递;$emit触发父组件的自定义事件)
             2) 使用provide、inject 传值
             3) 使用bus.js (通过定义公共实例文件来进行非父子组件之间的传值)
             4) 使用vuex 

  父子组件间传参,使用props、$emit 比较便利好用;

  跨组件传参,使用provide、inject 传值(爷孙组件比较便利),或者用bus.js和redux 。

和react的传参类比一下,套路相似,对比着学习更易懂,可以一起看react传值(父子传值,context传值,redux传值)

一、父子组件传参

1.  父 --->子

props形成一个单一向下的绑定,可以传值,也可以传函数,各种类型都可以

(1)在父组件的子组件标签上绑定一个属性,挂载要传输的变量
(2)在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使用 props: [“属性名”] 或 props:{   属性名1:{ type:..; default:..; reqired:true  //与default二选一},属性名2:XXX,属性名3:XXX    }

注意!!:在props中使用驼峰形式,模板中标签需要使用短横线的形式

例:  父组件    

   <template>
       //子组件
        <son :custom="100"></son>

    
     或  <child-com :num="num" :str="str" :obj="obj" :func="func"  :cmt-count="item.comm_count" />           // 模板中(建议)用短横线形式:cmt-count
   </tempalte>

<script>
   import ChildCom from './components/child';


   export default{
     components:{Son,ChildCom},     //引入子组件
     data(){
       return {    //这些要传给子组件
           num: 25, 
           str: '一个string类型的值',
           obj: {
               attr:'一个对象中的属性值'
           }

       }
     },
     methods:{
       func(){
           console.log('一个父组件的方法');
       }

     }
   }

</script>

     子组件  

 <template>
      <div>{{ cmtCount }}</div>
</template>

<script>

 export default{
       props:["custom"]
       或props:{

           num:{
               type:Number //数值型
           },
           str:{
               type:String,//字符型
               default:'hello' //str的默认值
           },
           obj:{
               type:Object,//对象类型
               reqired:true//是否必传的参数,布尔值true:必须传这个参数 ,默认为false,不是必传
           },
           func:{
               type:Function, //函数类型
               default(){   //不传递时默认值
                   return ()=>{}
               }
           }
           // props中的属性使用驼峰命名:cmtCount
           cmtCount: {
               type: [Number, String],
               default: 0
           }

       },
       data(){
         return{}
       },
       mounted(){
         this.func(); //调用父组件的func方法
       }
   }

</script>

2. 子 --->父

子组件$emit(事件名,参数) 绑定一个父组件的自定义事件,当这个事件被执行的时候就会将参数传递给父组件,而父组件通过v-on监听并接收参数。

 父组件  

 <template>
      //子组件
    <Son @handler="handlerMsg"/>
   </tempalte>


 </script>
   import Son from './components/child';
   export default{
     components:{Son},   //引入子组件
     methods:{
       handlerMsg(value){
            console.log('这个是父组件自定义的一个方法');
            console.log(value);  //输出100,是子组件通过this.$emit()触发传过来的
       }

     }
   }

 子组件  

   export default{
       mounted(){
         this.$emit('handler',100); //调用父组件的func方法
       }
   }

</script>

二、跨组件传参

1. 使用provide、inject 传值(vue2.2.0)
2. 使用bus.js (通过定义公共实例文件来进行非父子组件之间的传值)
3. 使用vuex (大项目里,兄弟组件多、传值比较复杂的用的多)

1. provide、inject 传值

允许一个祖先组件向其所有子孙后代注入一个依赖可以注入属性和方法,从而实现跨级父子组件通信。数据的流向只能是向下传递,就是大范围有效的props

概念:

简单来说就是父组件中通过provide来提供变量, 然后再子组件中通过reject来注入变量。

注意: 这里不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中回去数据

 父组件

<div>
      <button @click="changeName">修改姓名</button>
      <child-b />
</div>

<script>
export default{
    data() {
        return {
            name: "Jack"
        };
    },
    provide() {
        return {
            parentObj: this.name  //提供祖先组件的实例
        };
    },

    methods: {
        changeName() {
            this.name = 'Lily'
        }
    }
  }

</script>

 后代组件


<template>
  <div class="border2">
    <P>姓名:{{parentObj.name}}</P>
  </div>
</template>
<script>
  export default {
    inject: {
      parentObj: {
        default: () => ({})
      }
    } // 或者inject: ['parentObj']

  };
</script>
 

  2. 定义公共实例文件(bus.js)来传值

原理:通过 一个vue实例Bus作为媒介,专门负责传值。要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发(通过 $emit 发送)和监听(通过 $on 接收)来实现通信和参数传递。

详细来说,在 Vue 的prototype挂载了一个名字叫bus属性,这个属性指向 Vue 的实例。只要我们之后调用 Vue 或者new Vue时,每个组件都会有一个bus属性,因为以后不管是 Vue 的属性还是 Vue 的实例,都是通过 Vue 来创建的。bus的属性被挂载之前,可以在mounted中对事件进行监听。它是一个vue的实例,当然就有bus这个属性,有$on这个方法,就能监听到触发出来的事件。

 VueEvent.js文件 (公共实例文件)

import Vue from 'vue';

var VueEvent = new Vue();
export default VueEvent;  // 通过vue实例化出一个名称VueEvent对象

Home组件(发送消息)

<template>
  <div>
    <button @click="emitNews()">给其他组件广播数据</button>
  </div>
</template>

<script>
  import VueEvent from '../model/VueEvent.js'  //引入公共实例
  export default {
    name:"Home",
    data(){
      return {
        msg:"我是一个home组件",
      }
    },
    methods:{
      emitNews(){
        VueEvent.$emit('to-news',this.msg)  //点击发送数据
      }
    },
  }
</script>

New组件(接收信息)

 <script>
  import VueEvent from '../model/VueEvent.js'  //引入公共实例
  export default {
    name:"news",
    data(){
      return {
        msg:"我是一个news组件",
      }
    },
    mounted() {
      VueEvent.$on('to-news',(data)=>{     //监听,接收数据
        console.log(data);
      })
    },
  }
</script>

3. Vuex

1)state: 统一定义公共数据(类似于data(){return {a:1, b:2,xxxxxx}})

2)mutations : 使用它来修改数据(类似于methods)

3)getters: 类似于computed(计算属性,对现有的状态进行计算得到新的数据-------派生 )

4)actions: 发起异步请求

5)modules: 模块拆分
 

后面会补充例子,今天先写到这里。

Logo

前往低代码交流专区

更多推荐