Vue3组件间关系
实际业务开发过程中,一定会用到组件间通信,如父子组件通信、兄弟组件通信、爷孙组件通信,还有一些全局通信的场景
组件间关系可见下图:
本篇主要详解父子组件通信
父子组件传值常用方式
父子组件传值是开发过程中使用最多也是必掌握的方式 具体可以分为以下三种:
- 1.props/emits方式
- 2.v-model/emits方式
- 3.ref/emits方式
1.props/emits方式
父传子
父组件中引入子组件,然后在子组件上绑定需要传给子组件的值
<template>
<Child
title="用户信息"
:index="1"
:uid="userInfo.id"
:to-parent="getChilderVal"
/>
</template>
子组件通过props接收,
const props = defineProps<{
index: string
uid: number
}>()
子组件使用接收的值
const {
index,uid}=toRefs(props)
子传父
子组件定义emits,通过给子组件绑定一个事件触发emits:
const emits = defineEmits(['toParent'])
const selectChange = (id: number) => {
emits('toParent', id)
}
父组件通过getChilderVal接收:
<Child
title="用户信息"
:index="1"
:uid="userInfo.id"
:to-parent="getChilderVal"
/>
const getChilderVal=(id:number)=>{
console.log(id)
}
2.v-model/emits方式
对比 props / emits ,这个方式更为简单:
- 在 Father.vue ,通过 v-model 向 Child.vue 传值
- Child.vue 通过自身设定的 emits 向 Father.vue 通知数据更新
父传子
父组件直接通过v-model传值给子组件:
<template>
<Child
v-model:user-name="userInfo.name"
/>
</template>
子组件同理通过props接收:
const props = defineProps<{
userName: string
}>()
子传父
子组件通过"update"字段即可:
扫描二维码关注公众号,回复:
16489983 查看本文章
const emits = defineEmits(['update:userName'])
emits('update:userName')
3. ref/emits方式
ref 是可以用在 DOM 元素与子组件上面,所以,父组件也可以直接通过对子组件绑定 ref 属性,然后通过 ref 变量去操作子组件的数据或者调用里面的方法
父传子
比如导入了一个 Child.vue 作为子组件,需要在 template 处给子组件标签绑定 ref:
子组件:
<template>
<Child ref="child" />
</template>
父组件:
给子组件定义一个ref变量
const child = ref<HTMLElement>(null);
// 执行子组件里面的ajax函数
child.value.getList();
// 打开子组件里面的弹窗
child.value.isShowDialog = true;
子传父
子组件如果想主动向父组件通讯,也需要使用 emit,此处就不再重复讲解
父子组件方法相互调用
子组件调用父组件中方法
父组件:
<template>
<div>
<child :parent-handler="parentHandler" />
</div>
</template>
<script lang="ts" setup>
import child from "@/components/child";
const parentHandler=()=>{
console.log("这是父组件的方法");
}
</script>
子组件:
<template>
<div>
<button @click="handler">这是子组件的按钮</button>
</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
parentHandler: Function
}>()
};
//使用
props.parentHandler()
</script>
父组件调用子组件中方法
父组件:
<template>
<div class="mt-5">
<Son ref="RefChilde"></Son>
<div class="btn btn-primary my-2" @click="fnCallChild">
点我调用Son组件里的方法
</div>
</div>
</template>
<script lang="ts" setup>
import Son from "../components/Son.vue";
const RefChilde = ref(); //RefChilde 要和Son组件上的class名相同
const fnCallChild = () => {
RefChilde.value.sonFn(); //sonFn是子组件里的方法
};
</script>
子组件:
<template>
<div>
<h1>{
{
conts }}</h1>
</div>
</template>
<script lang="ts" setup>
const conts = ref("我是子组件");
const sonFn = () => {
conts.value = "我被父组件里调用了子组件的方法修改了数据";
};
</script>