美文网首页
vue组件通信

vue组件通信

作者: Ni_c746 | 来源:发表于2019-12-12 16:21 被阅读0次

vue深层的组件间通信

需求:当我们有一个组件的层级结构为 组件1 >> 组件2 >> 组件3的时候怎样通信最好

方案

1. 通过最常用的props和$emit来实现组件间的传值

  缺点:随着组件的嵌套的层级增多,每层的父组件都要监听子组件$emit发射的事件,太繁琐

2. 通过this.$parent和this.$children来相互调用组件的值或方法实现通信

  缺点:这个可以避免props和$emit的问题,但是假设我想在组件3用引用组件1的方法来改变某一个变量时,这时我们用这样写this.$parent.$parent,这样就很鸡肋,而且还必须管理父组件的层级,太不灵活

3. 通过eventBus来实现多层组件间的数据共享

  分析:eventBus实际上就是通过将共享的变量存在新建的一个vue的实例上,然后通过该实例的$emit和$on去实现数据的传递

  代码:

      eventBus.js

      import Vue from 'vue'

      export default new Vue()

      组件1

      import bus from 'common/js/eventBus'

      export default {

        methods: {

          busEmit() {

            bus.$emit('busEmit', '我是组件1发送的值')

          }

        },

        created() {

          this.busEmit()

        }

      }

      组件3

      import bus from 'common/js/eventBus'

      export default {

        created() {

          bus.$on('busEmit', (data) => {

            console.log(data)

          })

        }

      }

  优势:对于某一个多层嵌套的组件而言,他不会太繁琐

  缺点:但是对于有多个这种组件都要做多层件的传值时,由于所有共享值都是有这一个vue的实例去发送的,因此这种方案就不利于项目后期的状态维护,且耦合度也比较高

4. 通过vuex这个状态管理来共享数据

  分析:vuex可能是最常用的跨组件和跨页面的通信方式了,它相比于eventBus的方案,由于它可以将不同模块的数据进行模块化管理,通过namespace的方式访问,这使得其可维护性相对于前者比较高,并且也降低了数据转态之间的耦合

  缺点:假设如果有上百个组件都是这种嵌套的情况,那vuex也就要维护这些组件的一些数据和状态,组件内部要不停的去通过mutations,actions操作数据的变化,写法上就太麻烦了

5. 通过provide/inject来跨组件通信

  代码

      组件A

      <template>

        <div>

          {{name}}-{{age}}

          <b-comp />

        </div>

      </template>

      <script>

      import BComp from './b.vue'

      export default {

        provide() {

          return {

            compA: this,

            compA_age: this.age

          }

        },

        data() {

          return {

            name: '我是组件A',

            age: 18

          }

        },

        components: {

          BComp

        },

        methods: {

          test() {

            console.log('我是a组件的测试方法')

          }

        }

      }

      </script>

      组件b

      <template>

        <div>

          {{name}}

          <c-comp />

        </div>

      </template>

      <script>

      import CComp from './c.vue'

      export default {

        provide() {

          return {

            compB_name: this.name,

            compB: this

          }

        },

        inject: {

          getCompAdata: {

            from: 'compA',

            default: null

          },

          getCompAage: {

            from: 'compA_age',

            default: 19

          }

        },

        data() {

          return {

            name: '我是组件B'

          }

        },

        components: {

          CComp

        },

        created() {

          console.log(this.getCompAdata.name)

          this.getCompAdata.test()

          console.log(this.getCompAage) // 如果a组件中没有compA_age则会显示19

          this.getCompAdata.name = '我是组件A change by CompB' // 修改会影响a组件,和props传入对象一样,但是会抛出警告,证明他与props一样数据是单向传递的

          this.getCompAage = '18 change by CompB'

        }

      }

      </script>

      组件c

      <template>

        <div>

          我是组件C

        </div>

      </template>

      <script>

      export default {

        inject: {

          getCompB_name: {

            from: 'compB_name',

            default: ''

          },

          getCompB: {

            from: 'compB',

            default: ''

          },

          getCompA: {

            from: 'compA',

            default: ''

          }

        },

        data() {

          return {

            name: 'C'

          }

        },

        created() {

          console.log('c组件访问b组件的name属性:', this.getCompB_name)

          console.log('c组件访问b组件的this对象:', this.getCompB)

          console.log('c组件访问b组件的this对象调用组件A的name:', this.getCompB.getCompAdata.name)

          console.log('c组件访问a组件的name:', this.getCompA.name)

        }

      }

      </script>

  总结:这钟是目前来说比较好的方式,因为每个嵌套组件的状态是相对独立的,由他们自身去控制和维护,在写法上也比较简单,并且可以通过from字段定义引用的来源,以此来减少耦合

6. 在组件中使用inheritAttrs和$attrs传递数据

      组件a

      <template>

        <div>

          {{name}}-{{age}}-stars:{{obj.star}}

          <b-comp :name="name" :obj="obj" :age="age" :test="test"/>

        </div>

      </template>

      <script>

      import BComp from './b.vue'

      export default {

        data() {

          return {

            name: '我是组件A',

            age: 18,

            obj: {

              star: 2300

            }

          }

        },

        components: {

          BComp

        },

        methods: {

          test() {

            console.log('我是a组件的测试方法')

          }

        }

      }

      </script>

      组件b

      <template>

        <div>

          {{name}}

          <c-comp :name="name" v-bind="$attrs"/>

        </div>

      </template>

      <script>

      import CComp from './c.vue'

      export default {

        inheritAttrs: false,

        data() {

          return {

            name: '我是组件B'

          }

        },

        components: {

          CComp

        },

        created() {

          console.log('组件b', this.$attrs)

          this.$attrs.test()

          this.$attrs.obj.star = 4000

          this.$attrs.age = 100

        }

      }

      </script>

      组件c

      <template>

        <div>

          我是组件C

        </div>

      </template>

      <script>

      export default {

        inheritAttrs: false,

        props: {

          obj: {

            type: Object,

            default() {

              return {}

            }

          }

        },

        data() {

          return {

            name: 'C'

          }

        },

        created() {

          console.log('组件c的',this.$attrs)

        }

      }

      </script>

  总结:

  这种方式值的传递也是单向的,当传递一个引用类型的数据是,在子组件修改此参数数据,也会影响父级组件,但是它不会报错,当你传入的参数与子组件内部的props同名是,此时的$attrs会将该重复的数据去除掉,如果你中间的组件传一个名字相同的参数时,此时后面的会覆盖前面的同名参数的值。

[vue.md](./upload/201911/23/15744928021101847029.md)

相关文章

  • vue组件之间通信

    vue 组件之间通信 vue组件之间通信方式: 1.父组件通过props向下传数据给子组件,子组件通过$emit事...

  • 【Vue】组件通信(任意通信)

    本节所需的基础知识: 【Vue】组件通信(父传子props) 【Vue】组件通信(子传父$emit) 任意组件相互...

  • vue 组件通信方式 ,父子、隔代、兄弟 三类通信,六种方法

    Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面分别介绍每种通信方式且会说...

  • Vue相关知识点

    1、vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不...

  • Vue如何实现组件通信?

    Vue组件通信的三种情况: 父子通信 爷孙通信 兄弟通信 父子通信:父组件使用Prop向子组件传递数据,子组件通过...

  • VUE组件(传值,生命周期)

    VUE生命周期 VUE子传父组件通信 VUE非父子组件传值

  • Vue组件通信

    Vue组件通信 Vue组件关系可分为三大类: 父子组件 兄弟组件 跨级组件, 相应的组件之间的通信也分类三大类: ...

  • vue组件间通信的一些实用方法(VUE2.x)

    vue组件间通信的一些实用方法(VUE2.x) 一、父子组件间通信 常用的父子组件通信方法,一般涉及props和$...

  • vue组件通信(传值)

    1.父子通信 1.父组件(parent.vue) 子组件(child.vue) 2.子父通信 1.子组件(chil...

  • Vue组件通信

    总体来说,Vue中组件之间的通信场景如下图: 可以将其分为父子组件通信、兄弟组件通信、跨级组件通信。 1. 自定义...

网友评论

      本文标题:vue组件通信

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