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用于子传父
- 子组件定义emit
const emit = defineEmits(['on-click']) //接收一个数组,放自定义名称,以便于定义多个emit
- 子组件定义触发函数
const clickTap = () =>{
emit('on-click',list) //第一个参数是定义的emit的名字
}
<button @click="clickTap">派发</button>
- 父组件在子组件添加一个自定义事件(:on / @)
<Children @on-click="getList"></Children>
const getList = (list:number[])=>{
console.log('list from children',list)
}
v-model实现父子组件双向绑定
- 子组件input 添加input事件 ,绑定modelValue
- 声明input事件 props接受modelValue属性
- 声明一个emit,在input事件 执行 emits('update:modelValue', e.target.value)
- 父组件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 中的状态管理工具,使用这两个工具可以轻松实现组件通信。