当前位置: 首页 > 工具软件 > vue-chat > 使用案例 >

【vue】vue组件通讯的方式(vue2+vue3)

滑畅
2023-12-01

vue组件通讯的方式,并不局限于父子组件

一:props和$emit

适用于父子组件。

- 父组件向子组件传递 props 和事件

- 子组件接收 props ,使用 `this.$emit` 调用事件

直接代码是最方便的 每一步都有解释

--父组件
    <HelloWorld msg='传递给子组件的内容' @sayHi="sayHi"/>//当子元素emit'sayHi'的时候会调用父元素中的sayHi方法

  
methods: {
    sayHi(msg) {//收到子元素传递来的数据
      console.log(msg);//Hi
    }
  }

--子组件
<template>
  <h1 @click="clickHandler">{{ msg }}</h1>
</template>

export default {
  props: { //接受父元素传来的数据
    msg: String
  },
 emits: ['showMsg'], // Vue3 如果是vue2不需要写emits
  methods: {
    clickHandler() {
      this.$emit('sayHi', 'Hi')//向父元素传递数据
    }
  },
}

二:$refs

通过 `this.$refs.xxx` 可以获取某个子组件,前提是子组件中要设置 `ref="xxx"`。

【注意 1】要在 `mounted` 中获取 `this.$refs` 

【注意 2】在vue3中移除了$children 所以建议获取子组件的时候使用ref

父组件
<template>
    <HelloWorld ref='helloWord' msg='传递给子组件的内容' @sayHi="sayHi"/>

</template>

 mounted() {
    console.log(this.$refs.helloWord) //这里就能够打印子组件所有的内容包括data和method 可以直接调用子组件中的方法
  },

三:$parent

通过 `this.$parent` 可以获取父组件,并可以继续获取属性、调用方法等。

这个直接在子组件中调用即可,就不po代码了

四:自定义事件

适用于兄弟组件,或者是相差很远八杆子打不着的两个组件

这个分vue2和vue3  但是不管vue2还是vue3 都要记得销毁  区别就是vue2在beforeDestroy()中销毁 vue3在 beforeUnmount()中销毁

1-先说vue2

要注意引入event
event.js
import Vue from 'vue'
export default new Vue() //其实就是个vue实例 你要是不嫌弃麻烦愿意每次都event也不是不可以


----A组件

import event from './event'


 mounted() {

     addTitleHandler(title) {
            console.log('on add title', title)
        }
      // 绑定自定义事件
        event.$on('onAddTitle', this.addTitleHandler)//addTitleHandler是事件名字
     },

  
   beforeDestroy() {
        // 及时销毁,否则可能造成内存泄露
        event.$off('onAddTitle', this.addTitleHandler)
    }   
  
----B组件  
  methods: {
        addTitle() {
            // 调用自定义事件
            event.$emit('onAddTitle', this.title)
            this.title = ''
        }
    } 

2-vue3需要借助第三方库来实现自定义事件

这里我借助的是event-emitter (npm下载即可)

import ee from 'event-emitter'


const event = ee()

export default event

其他的与vue2一致 再次提醒!!在vue3中销毁是

  beforeUnmount() {
    event.off('onAddTitle', this.addTitleHandler)
  },

五:$attr

$attrs存储是父组件中传递过来的,并且没有在 `props` 和 `emits` 中定义的属性和事件

相当于 props 和 emits 的一个补充

【注意】在props 和 emits中有的 就不会在this.$attrs中出现了

【注意】在vue2 的时候 事件会在$listener中获取 但是vue3移除了它,或者说是合并到了attrs中

另外假设我们是嵌套组件A套B B套C 如果c想要获取A的内容 就可以在B中 使用 v-bind=“$attrs” 这样C中可以获取到A和B所有没在props 和 emits 中的内容

组件A
<template>
    <p>A <input v-model="name"></p>

    <B
        :a="a"
        :b="b"
        @getA="getA" 
        @getB="getB"
        
    ></B>
</template>

组件B
<template>
    <p>B <input v-model="name"></p>

    <C
        :y="y"
        :z="z"
        @getZ="getZ"
        @getY="getY"
        v-bind="$attrs"//相当于把B获取到的attrs全部传递给了c
    ></C>
</template>

export default {

    props: ['a'],
    emits: ['getA'],
    data() {
        return {
            y: 'yyy',
            z: 'zzz'
        }
    },
 created() {
//可以获取到b和getb 因为他们没有在props和emit里
         console.log(this.$attrs)  
    },
    methods: {
  
        getY() {
            return this.y
        },
        getZ() {
            return this.z
        }
    },
   
}

组件C
export default {

    props: ['y'],
    emits: ['getY'], 
    created() {
 //可以获取到b,z和getb getz 因为他们没有在props和emit里 
//获取到b和getb是因v-bind如果没有写这个属性 只会获取到B组件传来的不再props和emit中的数据和方法
         console.log(this.$attrs) 
    },
   }
    
   
}

六:provide/inject

这个我个人认为是一个比较完美的能够用于多层嵌套组件的方案

只要在最上级provide一个属性 他的子孙们不管相隔多少层都可以获取到这个数据

【注意】vue2 和 vue3 写法有些许差异 在下面代码中显示了

【注意】上一层是否inject 都不影响本层组件获取provide

组件A
<template>
    <p>A <input v-model="name"></p>
    <B></B>
</template>

import { computed } from 'vue'

export default {
    data() {
        return {
            a:'aa',
        }
    },
    //传递一个静态数据 vue2 和 vue3 写法一致
    // provide: {
    //     info: 'aaa' 
    // }

    //vue2传递data中的数据
    provide() {
        return {
            info:this.a
        }
    }

    //vue3传递data中的数据
    provide() {
        return {
            info: computed(() => this.a)
        }
    }
}

组件B
<template>
    <p>{{info}}</p> //可以在这里直接使用

    <C></C>
</template>

export default {

   inject: ['info'] //获取到info
   
}

组件C 同理 无论组件B是否使用inject 都不影响C


七:vuex

vuex就是全局数据存储 之后会写一篇把之前总结在笔记里的内容分享给大家
(哈哈哈 一直拖着这个主要还是因为懒,因为分享就要写的能让大家看懂 自己整理只要自己看懂就好了)

 类似资料: