vue3组件间通信方式
vue3组件间通信方式
1. props(父给子)
props:vue3中,子组件获取数据,直接defineProps([‘xxx’]),即可在模板中使用,但是props是只读的。
2. 自定义事件(子给父)
vue框架事件分为两种:原生DOM事件、自定义事件。
原生DOM事件会带回调函数,里面必定包含基础的event事件对象。
在vue3中,原生DOM事件不管放在标签or组件标签上,都是原生DOM事件。
自定义事件完成父子组件传递数据。
1 | //子组件Event |
1 | //父组件 |
####3. 全局事件总线(兄弟之间)
使用mitt插件。
安装完成后,新建bus文件夹,里面新建index.ts。
1 | import mitt from 'mitt'; |
接着即可完成兄弟组件数据通信。
1 | //接收数据者 |
1 | //发送数据者 |
4. v-model
v-model:基础用法为收集表单数据,完成数据双向绑定。
但是也可以实现组件之间通信!
v-model在组件上使用:相当于给子组件传递props[modelValue],绑定自定义事件update:modelValue
1 | //父组件 |
1 | //子组件Event |
5. useAttrs
此方法可以获取组件标签身上的属性与事件
1 | //父组件 |
1 | //子组件HindButton |
注意:props与useAttrs方法都可以获取父组件的属性和属性值,但是props优先级更高。
6. ref与$parent
ref:可以获取真实的DOM节点,可以获取到子组件的实例VC。
$parent:可以获取到父组件的实例。
7. provide与inject
实现隔辈组件通信。
1 | //祖先组件 |
1 | //后辈组件Evenet |
注意:可以修改数据,不是只读,和props不一样!
8. pinia
vuex:集中式管理状态容器,可以实现任意组件间通信!
核心概念:state、mutations、actions、getters、modules。
pinia:集中式管理状态容器,可以实现任意组件间通信!
核心概念:state、actions、getters。
选择式写法
在store文件夹下新建文件index.ts,创建大仓库。
1
2
3import {createPinia} from 'pinia';
let store = createPinia();
export default createPinia在main.js引入仓库。
1
2import store from './store';
app.use(store);接着在store文件夹下创建modules文件夹,存放小仓库,新建info.ts。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import {defineStore} from 'pinia';
//defineStore方法返回一个函数,让组件可以获取仓库数据
//参数:小仓库名字+小仓库配置对象
let useInfoStore = defineStore("info", {
//存储数据:state
state: () => {
return {
a: "asdasa"
}
},
actions: {
updateA(param){
//直接对this.a进行修改
}
},
//计算属性
getters: {
total(){
//返回计算结果res
}
}
})
export default useInfoStore;此时,组件即可选取仓库,获取对应数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<template>
<div>
<button @click="updateState">修改数据</button>
</div>
</template>
<script setup>
import {useInfoStore} from '../../store/modules/info.ts';
let info = useInfoStore();
const updateState = () => {
//可以直接对info.a进行修改
//也可以调用仓库里面actions自定义的方法
}
</script>组合式写法
在store/modules文件夹下,新建todo.ts。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import {defineStore} from 'pinia';
import {ref} from 'vue';
//参数:小仓库名字+小仓库配置对象
let useTodoStore = defineStore("todo", () => {
let todos = ref([{a: "asdasda"}]);
//返回一个对象:属性和方法。以给组件使用
return {
todos,
update(){
...
}
}
});
export default useTodoStore;接着组件开始调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14<template>
<div>
<button @click="updateTodo">修改数据</button>
</div>
</template>
<script setup>
import {useTodoStore} from '../../store/modules/todo.ts';
let todo = useTodoStore();
const updateTodo = () => {
todo.update();
}
</script>
9. 插槽
默认插槽
具名插槽
1
2
3//子组件Test
<slot name="a"></slot>
<slot name="b"></slot>1
2
3
4
5
6
7
8
9
10父组件
<Test>
<template v-slot:a>
...
</template>
<template v-slot:b>
...
</template>
</Test>作用域插槽(很常用)
可以传递数据的插槽,子组件可将数据回传给父组件,父组件决定如何将数据在子组件内展示。




