VUE3组件间通讯的7种方式

270 阅读1分钟

VUE3组件间通讯的7种方式

本文总结了vue3中常见的七种组件间通讯方式

  • props
  • emit
  • v-model
  • refs
  • Provide/inject
  • enentBus
  • Vuex4/pinia

props

props用于父组件向子组件传值

父组件以数据绑定的形式声明要传递的数据,子组件通过defineProperty()方法创建props对象,即可拿到父组件传来的数据。

父组件:

 <Props :list="list"></Props>

子组件:

 <script setup lang="ts">
 type props = {
   list: { name: string }
 }
 const props = defineProps<props>()
 </script>

emit

emit用于子传父

  1. 子组件定义emit
 const emit = defineEmits(['on-click']) //接收一个数组,放自定义名称,以便于定义多个emit
  1. 子组件定义触发函数
 const clickTap = () =>{
   emit('on-click',list) //第一个参数是定义的emit的名字
 }
 <button @click="clickTap">派发</button>
  1. 父组件在子组件添加一个自定义事件(:on / @)
 <Children  @on-click="getList"></Children>
 const getList = (list:number[])=>{
   console.log('list from children',list)
 }

v-model实现父子组件双向绑定

  1. 子组件input 添加input事件 ,绑定modelValue
  2. 声明input事件 props接受modelValue属性
  3. 声明一个emit,在input事件 执行 emits('update:modelValue', e.target.value)
  4. 父组件v-model一个值即可

子组件:

 <template>
   <div><input @input="changeUpdate" :value="modelValue" /></div>
 </template>
 ​
 <script setup lang="ts">
 import { reactive, ref, defineEmits } from 'vue'
 type Props = {
   modelValue: string
 }
 const props = defineProps<Props>()
 const emits = defineEmits()
 const changeUpdate = (e) => {
   console.log(e.target.value)
   emits('update:modelValue', e.target.value)
 }
 </script>

父组件

<div>
    <Emit v-model="content"></Emit>
    {{ content }}
  </div>

ref

使用ref可以直接得到子组件的定义值,但要注意:在父组件要使用getCurrentInstance得到this,在子组件使用defineExpose暴露变量。

子组件

<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script setup lang="ts">
import { ref, watchEffect } from 'vue';
let message = ref<string>('test')
const alertMessage = () => {
  alert(message.value)
}
defineExpose({
  alertMessage,
  message
})
</script>

父组件

<template>
  <div>
    <Ref1 ref="children"></Ref1>
    <button @click="showMessage">change</button>
  </div>
</template>

<script setup lang="ts">
import { getCurrentInstance, ref, watchEffect } from 'vue';
import Emit from './components/Children/Emit.vue';
import Ref1 from './components/Children/Ref.vue';
let content = ref<string>('father')
const currentInstance = getCurrentInstance()
const showMessage = () => {
  // console.log(currentInstance.refs.children)
  currentInstance.refs.children.message = 'testhahaha'
}
watchEffect(() => {
  console.log(content.value)
})
</script>

provide/inject

用于多重嵌套的组件,无论嵌套的多深,都可以得到。

父组件

provide('info', info)

子组件

const list = inject('info')

eventBus

Vue 3 中移除了 eventBus,但可以借助第三方工具来完成。Vue 官方推荐使用 mitt 或 tiny-emitter。

vuex/pinia

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