vue3组件间通信的方式

在使用vue时,我们经常会把不同的模块拆分成不同的组件,而组件之间有的需要传递数据,所以组件间的数据通信就非常重要了。

而在vue中,组件之间的关系大致可以分为以下两种:

  • 父子组件之间通信

  • 非父子组件之间通信(兄弟组件、祖孙组件等)

  1. props/$emit

对于父子组件通信而言,最简单的方式就是 利用 props。 父组件可以通过props的方式向子组件传递数据,而子组件通过$emit可以向父组件通信。

父组件:

<template>
  <div class="Father">
    <ChildComponent :list="list" @changeList="changeList"/>
  </div>
</template>

<script>
import ChildComponent from '../Son/SonComponent.vue'
import {ref} from 'vue';
const list = ref(['HTML','CSS','JS'])
export default {
    name: 'FatherComponent',
    components:{
        ChildComponent
    },
    setup(){
        function changeList(value){
            list.value.push(value)
        }
        return {
            list,
            changeList
        }
    }
}
</script>

子组件:

<template>
  <div class="Son">
    <h1>This is Child</h1>
    <ul>
        <li v-for="item in list" :key="item.index">{
    
    {item}}</li>
    </ul>
    <button @click="$emit('changeList','Python')"></button>
  </div>
</template>

<script>
export default {
    name: 'ChildComponent',
    props: {
        list: Array,
    },
    setup(props){
        console.log(props.list);
    }
}
</script>
利用props将父组件数据传递给子组件
注意点:
1、props只可以从上一级组件传递到下一级组件(即父子组件),即所谓的单向数据流。【如有需要,可以通过data属性接收或使用computed属性进行转换】
2、props只读,不可被修改,所有修改都会失效并警告。
子组件想将数据传递给父组件时,使用 $emit触发自定义事件,父组件使用v-on(缩写为@)来监听事件

  1. refs

父组件获取子组件的属性或者调用子组件方法

子组件:

<template>
  <div class="Son">
    <h1>{
    
    {message}}</h1>
  </div>
</template>

<script setup>
import  { ref, defineExpose } from 'vue'
let message = ref('I am Child')
const showMessage = () => {
    alert('123')
}
defineExpose({
    message,
    showMessage
})
</script>

父组件:

<template>
  <div class="Father">
    <ChildComponent ref="child"></ChildComponent>
    <button @click="show">Show Child Message</button>
  </div>
</template>

<script setup>
import ChildComponent from '../Son/SonComponent.vue'
import {ref} from 'vue';

const child = ref()
const show = () =>{
    console.log(child.value.message);
    child.value.showMessage();
}
</script>

3. provide/inject

provide/inject 是 Vue中提供的一对API。无论层级多深,API都可以实现父组件到子孙组件的数据传递。

provide:提供一个值,可以被后代组件注入

inject: 注入一个由祖先组件或整个应用提供的值

父组件:

<template>
  <div class="Father">

  </div>
</template>

<script setup>
import {provide} from 'vue'

provide('eric','eric_content')
</script>

子组件:

<template>
  <div class="Son">
    <h1>{
    
    {message}}</h1>
  </div>
</template>

<script setup>
import  { inject } from 'vue'
let message = inject('eric')
console.log(message);
</script>

4. eventBus

eventBus,又称事件总线,其原理就是 事件订阅发布。在vue中可以使用它来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以通知其他组件。

但是vue3中移除了eventBus,但是可以借助第三方工具,如mitt来实现。其原理还是eventBus

使用步骤:

安装:
cnpm i mitt -S

封装:

import mitt from 'mitt'
const mitt = mitt()
export default mitt

使用:

组件1:

<template>
  <div class="component1">
    <button @click="handleClick">click</button>
  </div>
</template>

<script setup>

import bus from '../mitt'
const handleClick = () => {
    bus.emit('handleChange','eric')
}
</script>

组件2:

<template>
  <div class="component2">
    123
  </div>
</template>

<script setup>
import bus from '../mitt'
import { onMounted, onUnmounted } from 'vue'

onMounted(()=>{
    bus.on('handleChange',(info)=>{
        console.log(info);
        alert(123)
    })
})

onUnmounted(()=>{
    bus.off('handleChange',someMethod)
})
</script>

5. vuex/Pinia

Vuex 和 Pinia 是 Vue 3 中的状态管理工具,使用这两个工具可以轻松实现组件通信

猜你喜欢

转载自blog.csdn.net/m0_56698268/article/details/129663910