vue3 组件通信
- 和vue2的通信方式基本一致,只是存在写法上的差异
props/emit
- setup函数接收两个参数,props和context(上下文,其中有一个 emit)
- 用法展示
// 父组件
<template>
<i-button :type='type' @onClick="click"> 按钮 </i-button>
</template>
<script> import { ref } from "vue"
import IButton from './IButton'
export default{
components:{
IButton
},
setup(){
const type = ref('primary');
const click = val => {
// 父组件接收子组件的值
console.log(val) // 1
}
return{
type,
click
}
}
} </script>
// 子组件
<template>
<button :type='type' @click="handleClick">
<slot></slot>
</button>
</template>
<script> export default{
props:{
type:{
type:String.
default:'default'
}
},
setup(props,{ emit }){
const handleClick = val => {
// 子组件向父组件传参
emit('onClick',1);
// 父组件监听的事件名要与这里注册的事件名保持一致
}
return{
handleClick
}
}
} </script>
ref
- vue2.x是通过 this.$children 等方法来获取的,但是 vue3中的setup函数中不能访问this,所以要使用其他的方法来获取实例对象
- 用法展示
// 父组件
<template>
<i-button ref="btnRef" :type='type' @click="click">
按钮
</i-button>
</template>
<script> import { ref } from "vue"
import IButton from './IButton'
export default{
components:{
IButton
},
setup(){
const type = ref('primary');
const btnRef = ref(null);
const click = () => {
// 父组件调用子组件的方法来获取数据
const val = btnRef.value.sendParent();
console.log(val); // 1
}
return{
type,
btnRef,
click
}
}
} </script>
// 子组件 只写逻辑的部分
< script>
export default{
setup(){
const sendParent =()=>{
return '1'
}
return {
sendParent // 一定要return出去
}
}
}
</script>
provide/inject
- 个人觉得相对于2.x我也觉得使用更方便
- 这种通信方法比较适合多层嵌套和平级组件使用
- 缺点:不好追踪修改,导致代码混乱
- 用法展示
// 父组件 只写逻辑的部分
< script>
import { ref, provide } from "vue";
export default{
setup(){
const num = ref(0);
// 第一个参数是key值,
// 第二个参数是value
provide('num',num);
}
}
</script>
// 子组件 只写逻辑的部分
< script>
import { inject } from "vue";
export default{
setup(){
const num = inject('num');
console.log(num) // 0
}
}
</script>
vuex
- vuex方式适合多组件数据统一,而且方便追溯
- 用法展示(vuex的配置项不会的请参考:vuex4学习笔记)
// 父组件 只写逻辑的部分
< script>
import { useStore } from "vuex";
export default{
setup(){
const store = useStore();
const changeChildrenNum = () => {
store.dispatch("changeNum",1)
}
return {
changeChildrenNum
}
}
}
</script>
// 子组件 只写逻辑的部分
< script>
import { useStore,watch } from "vuex";
export default{
setup(){
const store = useStore();
watch(
() => store.getters.num,
(newVal,oldVal) => {
// 父组件点击触发
console.log(newVal); // 1
}
)
return {
changeChildrenNum
}
}
}
</script>