美文网首页前端核心知识
vue2.0父子组件以及非父子组件通信传参详解

vue2.0父子组件以及非父子组件通信传参详解

作者: 郝艳峰Vip | 来源:发表于2018-11-01 15:04 被阅读0次

    写在前面


    之前每次写项目的时候老是忘记vue的组件之间的传参,很不方便,每次都是现查,趁着这次折腾非父子组件的传参,学习记录下来,以方便以后学习使用。

    1.父组件传递数据给子组件

    父组件写法

    <parent>
        <child :child-msg="msg"></child>//这里必须要用 - 代替驼峰
    </parent>
    
    data(){
        return {
            msg: [1,2,3]
        };
    }
    

    子组件接收写法

    第一种:
    props: ['childMsg']
    第二种:
    props: {
        childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告
    }
    第三种:
    props: {
        childMsg: {
            type: Array,
            default: [0,0,0] //这样可以指定默认的值
        }
    }
    可以根据自己的需要选择使用哪一种
    

    2.子组件与父组件通信

    vue文档中是这么解释的:如果子组件想要改变数据呢?这在vue中是不允许的,因为vue只允许单向数据传递,这时候我们可以通过触发事件来通知父组件改变数据,从而达到改变子组件数据的目的.


    子组件写法

    <template>
        <div @click="up"></div>
    </template>
    
    methods: {
        up() {
            this.$emit('upup','hehe'); //主动(dispatch)触发upup方法,'hehe'为向父组件传递的数据
        }
    }
    

    父组件写法

    <div>
        <child @upup="change" :msg="msg"></child> //监听子组件触发的upup事件,然后调用change方法
    </div>
    methods: {
        change(msg) {
            this.msg = msg;
        }
    }
    

    3.非父子组件通信

    vue文档中是这么解释的:如果2个组件不是父子组件那么如何通信呢?这时可以通过eventHub来实现通信.
    所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件.

    第一种:

    创建一个公共的js,美其名曰:bus.js作为中间仓库来传值。
    //bus.js
    import Vue from 'vue'
    export default new Vue()
    

    组件A中

    <template>
      <div>
        A组件:
          '$emit' 官网解释:  ---事件触发器
        <span>{{elementValue}}</span>
        <input type="button" value="点击触发" @click="elementByValue">
      </div>
    </template>
    <script>
      // 引入公共的bus,来做为中间传达的工具
      import Bus from './bus.js'
      export default {
        data () {
          return {
            elementValue: 4
          }
        },
        methods: {
          elementByValue: function () {
           通过事件中心去发射'Assembly'自己命名的,方法,this.elementValue为传的参数。
            Bus.$emit('Assembly', this.elementValue)
          }
        }
      }
    </script>
    

    组件B中

    <template>
      <div>
        B组件:  
       通过$on方法来接受该方法以及传的参数
        <input type="button" value="点击触发" @click="getData">
        <span>{{name}}</span>
      </div>
    </template>
    <script>
      import Bus from './bus.js'
      export default {
        data () {
          return {
            name: 0
          }
        },
        mounted: function () {
          var vm = this
          // 用$on事件来接收参数   并且调用了在a组件中出发的方法
          Bus.$on('Assembly', (data) => {
            console.log(data)
            vm.name = data
          })
        },
        methods: {
          getData: function () {
            this.name++
          }
        }
      }
    </script>
    

    这就完成了非父子组件的传参,不过小编在学习过程中还发现了另一种方法:真是学自折腾来啊

    不理解的小伙伴可以参考官网的解释:

    微信图片_20180920204827.png

    第二种:说明一下

    由于vue2.0 移除了1.0中的dispatch 和broadcast 这两个组件之间通信传递数据的方法 ,官方的给出的最简单的升级建议是使用集中的事件处理器,

    而且也明确说明了 一个空的vue实例就可以做到,因为Vue 实例实现了一个事件分发接口.方法就是,在vue初始化的时候给data添加一个 名字为eventhub 的空vue对象


    main.js中

    new Vue({
      el: '#app',
      router,
      render: h => h(App),
      data: {
        eventHub: new Vue()
      }
    })
    

    好的 这个时候 你就可以一劳永逸了,在任何组件都可以调用事件发射 接受的方法了.
    如何获取到这个空的vue对象 eventhub呢.在组件里面直接调用这个

    某一个组件内调用事件触发
    //通过this.$root.eventHub获取此对象
    //调用$emit 方法
    this.$root.eventHub.$emit('YOUR_EVENT_NAME', yourData)
    
    另一个组件内调用事件接受,当然在组件销毁时接触绑定,使用$off方法
    mounted(){
    this.$root.eventHub.$on('YOUR_EVENT_NAME', (yourData)=>{
        console.log(yourData)
    })
    }
    

    结束语

    总结一下,收获还是蛮大的,但是不知道是记性不好了,还是老了,写一段时间的别的项目就忘掉了,还是需要重新温习一遍,真是应了那句古话,好记性不如烂笔头。好了不多说了,希望可以帮助到自己和小伙伴们。

    相关文章

      网友评论

        本文标题:vue2.0父子组件以及非父子组件通信传参详解

        本文链接:https://www.haomeiwen.com/subject/aqdxxqtx.html