Vue 组件间的通讯方式
vue3组件通信方式为以下几种
- props
- $emit
- $expose / ref
- $attrs
- v-model
- provide / inject
- Vuex
- mitt
props
defineProps({
// 写法一
msg2:String
// 写法二
msg2:{
type:String,
default:''
}
})
$emit
// child.vue
<template>
// 写法一
<div @click="$emit('myclick')">按钮</div>
// 写法二
<div @click="handleClick">按钮</div>
</template>
// 方法一
const emitFn = defineEmits(['myClick']);
// 方法二
const handleClick = () => {
emitFn('myClick','这是发送给父组件的信息');
}
// Parent.vue
<template>
<child @myClick="onMyClick"></child>
</template>
<script setup>
import child from "./child.vue"
import onMychilk = (msg) => {
console.log(msg) // 父组件收到的信息
}
</script>
$expose / ref
父组件获取子组件的实例的方法或者属性
// 子组件
import { defineExpose } from 'vue';
const initial = ref(10);
const count = ref(0);
defineExpose({
count,
initial
})
// 父组件
<HelloWorld ref="helloWorld" />
const helloWorld = ref(null);
onMounted(() => {
console.log('count: ' + helloWorld.value.count)
console.log('initial: ' + helloWorld.value.count)
})
attrs
attrs:包含父作用域除class和style除外的非props属性集合
// 父组件
<HelloWorld title="test" />
// 子组件
import { useAttrs } from "vue";
const attr = useAttrs();
console.log(attr);
v-model
支持多个数据双向绑定
// 父组件
<HelloWorld v-model:key1="keyVal.key" v-model:value="keyVal.value" />
const keyVal = reactive({
key: 'name',
value: 'bobo'
})
// 子组件
import { defineEmits, defineProps } from "vue";
defineProps({
key1: String,
value: String,
});
const emits = defineEmits(['update:key1', 'update:value']);
const updateNewKeyVal = () => {
emits('update:key1', '新的key');
emits('update:value', '新的value');
}
<p>key: {{key1}}</p>
<p>value: {{value}}</p>
<div>
<button @click="updateNewKeyVal">更新信息</button>
</div>
provide / inject
provide/inject为依赖注入 provide:可以让我们指定想要提供给后代组件的数据 inject:在任何后代组件中接受想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来用
// 父组件
<script setup>
import { provide } from 'vue'
const name = provide('name')
console.log('name','沐华')
</script>
//子组件
<script setup>
import { inject } from 'vue'
const name = inject('name')
console.log(name) //木华
</script>
vuex or pinia
状态管理库
mitt
- Vue3中已经没有了EventBus跨组件通信,替代方案mitt.js,但原理方式EventBus是一样的
- 安装方式 npm i mitt -S
// 封装
mitt.js
import mitt from 'mitt'
const mitt = mitt()
export default mitt
// 组件A
<script setup>
import mitt from './mitt'
const handleClick = () => {
mitt.emit('handleChange')
}
</script>
// 组件B
<script setup>
import mitt from './mitt'
import { onUnmounted } from 'vue'
const someMethod = () => {}
mitt.on('handleChange',someMethod)
onUnmounted(()=>{
mitt.off('handleChange',someMethod)
})
</script>