问渠那得清如许?为有源头活水来。 ——朱熹
最近在自学vue3 + ts相关的技术,由于自己本身就对vue2甚至整个前端的技术都没有详细的了解,因此刚开始学起来就比较的慢。尤其是父子组件通信部分,算是耗费了一个周末的时间才大概搞懂。因此,此博客用于记录自己所学。
对于Vue中,父子组件通信应该是比较常见的场景。主要就是父与子通信,和子与父通信。
1. 父与子通信
父给子传递消息,主要是通过子组件的props来接收数据。如我们可以定义一个组件,里边主要是两个Button,对于Button上显示的内容,可以通过父组件来给传递。首先是子组件的代码
<!-- HelloWorld.vue -->
<template>
<el-button type="primary">{{ bt1 }}</el-button>
<el-button type="success"">{{ bt2 }}</el-button>
</template>
<script setup lang="ts">
// vue3的语法糖,直接定义props。里边分别为两个变量,bt1和bt2
defineProps({
bt1: String,
bt2: String,
})
</script>
<style scoped>
</style>
然后对于父组件,只需要在定义子组件时,将变量名作为attribute传入即可,如下是父组件的代码
<!-- App.vue -->
<template>
<!-- 将bt1的值赋值为“加1” ,bt2的值赋值为“减2”-->
<hello-world bt1="加1" bt2="减1"" />
</template>
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>
<style scoped>
</style>
则,运行代码,则是如下的效果
如上,则是父组件 —> 子组件的通信
2. 子与父通信
子组件返回给父组件消息,要相较于父组件传递消息给子组件要复杂些。主要使用过emit来回调父组件定义的相关方法来实现。
即子组件在触发某个行为动作时,回调父组件的方法来通知父组件相关变化
比如我们要实现上述的两个按钮,在+1 -1的操作下,让父组件显示对应操作后的值
首先看子组件
<template>
<el-button type="primary" @click="clickA">{{ bt1 }}</el-button>
<el-button type="success" @click="clickB">{{ bt2 }}</el-button>
</template>
<script setup lang="ts">
defineProps({
bt1: String,
bt2: String,
})
const emit = defineEmits<{
//定义一个回调方法,可以理解为回调父组件传入的attribute为ccc的方法,入参为一个number类型的变量
(e: 'ccc', num: number): void,
}>()
let num: number = 0
//点击 加1 按键调用此方法
const clickA = () => {
num++
//回调父组件 attribute为ccc的方法
emit('ccc', num)
}
//点击 减1 按键调用此方法
const clickB = () => {
num--
//回调父组件 attribute为ccc的方法
emit('ccc', num)
}
</script>
<style scoped>
</style>
对于子组件,主要是再按下按钮后,对num变量进行 +1/-1的操作
对于父组件,主要实现的是给子组件出传入一个方法,且方法对应的attribute为ccc
<template>
<!-- ccc的方法为printNum -->
<hello-world bt1="加1" bt2="减1" @ccc="printNum" />
<el-divider />
<!-- 展示n值 -->
{{ n }}
</template>
<script setup lang="ts">
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue'
const n: any = ref(0)
//此方法主要是接受一个入参,并将其赋值给本地定义的n,并将其值打印出
const printNum = (num: any) => {
n.value = num
console.log(n.value)
}
</script>
<style scoped>
</style>
对于父组件,主要创建了一个名为printNum的方法,方法中主要将传入的参数赋值给本地定义的变量n,并打印出n的值。而且在前端实时展示n的值
这样,我们运行代码,就可以实现点击自定义组件的按钮,来改变父组件定义的值了。
这样,我们来回点击 加1 减1按钮,就可以实时的改变父组件中的值
3.踩坑记录
对于工作后的学习,基本上就是需要用啥直接学啥。根本没有时间也没有精力像大学时候来系统性的学习某一项技能。这种学习方式有利有弊。利的是能很快的学以致用,学习的效率较高。弊的是在学习技术的路上会有很多坎坷,可能遇到一点的小问题就要停下来解决很久。
在今天研究vue子组件通信父组件时候,遇到了一个坑。就是自己在用 const n: any = ref(0)
来定义变量后,在使用过程中,直接是用n = xxx
来赋值的,这样的赋值方式,虽然在log上打印是赋值成功的,但是前端上面展示的值却不变。最后经过查相关资料才明白,原来是使用ref()
来定义变量时候,在使用过程中要加上.vlaue
来赋值,即n.value = num
只有经过了这样的赋值,前端展示的值才会跟着改变。