本篇介绍的是vue中父子组件是这么通信的,对比HarmonyOS NEXT开发来说,vue中的父子组件步骤通信比较繁琐,没有HarmonyOS NEXT的通讯简便,但是大致的步骤还是差不多的。
在HarmonyOS NEXT中只需要使用@Prop、@Link或者@Provide/@Consume、@Observed/@ObjectLink修饰变量,也可以配合回调函数。
接下来我将通过一个简单的例子(结尾有完整代码)来介绍vue中的父子组件通信。
将数据传给子组件
首先,我们先创建好一个子组件Son.vue,父组件为根组件App.vue,将子组件引入父组件中,并在父组件定义一个钱包。
父组件布局:
<script setup lang="ts">
import {ref} from 'vue'
// 导入子组件
import HmSon from './components/HmSon.vue'
// 1.定义一个属性 钱包
const money = ref(10000)
</script>
<template>
<div class="father">
父组件 钱包: {{ money }}元
<!-- 子组件-->
<HmSon />
</div>
</template>
<style scoped>
.father{
width: 600px;
height: 400px;
border: 10px solid aquamarine;
}
</style>
子组件:
<script setup lang="ts">
</script>
<template>
<div class="son">
子组件 钱包:
</div>
</template>
<style scoped>
.son{
width: 300px;
height: 200px;
border: 10px solid black;
}
</style>
接下来将父组件的钱包数据传给子组件,先通过withDefaults和defineProps定义一个属性用来接收父组件的数据,并设置初始值。
子组件:
<script setup lang="ts">
// 给子组件接收数据的属性设置默认值
withDefaults(defineProps<{
money: number
}>(),{
// 设置默认值 父组件传过来后会覆盖掉
money: 200
})
</script>
父组件将数据传过去,子组件进行渲染
// 使用属性绑定指令将money属性传给子组件
<HmSon :money="money" />
// 子组件进行渲染
<div class="son">
子组件 钱包: {{ money }}
</div>
子组件注册事件修改父组件数据
刚刚完成的传输数据还是很简单的,接下来实现让子组件修改父组件的数据,每点一次按钮,让父组件的钱包 +1000
首先,在子组件中先写一个按钮,并使用defineEmits注册一个事件。
<script setup lang="ts">
// 定义事件,通知父组件修改money的值
const emit = defineEmits<{
// e:'changeMoney'为事件名,固定写法
// money: number 为传给父组件值的类型,不需要传值给父组件可以不写
(e:'changeMoney',money: number): void
}>()
</script>
<div class="son">
子组件 钱包:{{ money }}元
<!-- 使用事件,点击时通知父组件修改,并将1000传过去 -->
<button @click="emit('changeMoney',1000)">
money+1000
</button>
</div>
父组件定义一个箭头函数,填写计算表达式,并传给子组件。
<script setup lang="ts">
// 导入子组件
import HmSon from './components/HmSon.vue'
import {ref} from 'vue'
// 1.定义一个属性
const money = ref(100)
// 2.提供计算(填子组件挖的坑) value: number为子组件传过来的值
const changeMoney =(value: number) => {
money.value += value
}
</script>
<div class="father">
父组件 钱包: {{ money }}元
<!-- 将 money传给子组件 -->
<HmSon :money="money"
@changeMoney="changeMoney"/>
</div>
至此,一个简单的父子通信就算完成了,实际上如果不需要给子组件的属性设置初始值时只用defineProps就可以
完整代码:
父组件(App.vue)
<script setup lang="ts">
// 导入子组件
import HmSon from './components/HmSon.vue'
import {ref} from 'vue'
// 1.定义一个属性
const money = ref(100)
// 2.提供计算(填子组件挖的坑) value: number为子组件传过来的值
const changeMoney =(value: number) => {
money.value += value
}
</script>
<template>
<div class="father">
父组件 钱包: {{ money }}元
<!-- 将 money传给子组件 -->
<HmSon :money="money"
@changeMoney="changeMoney"/>
</div>
</template>
<style scoped>
.father{
width: 600px;
height: 400px;
border: 10px solid aquamarine;
}
</style>
子组件(Son.vue)
<script setup lang="ts">
// 定义一个属性,接收父组件传过来的值
// defineProps<{
// money: number
// }>()
// 给子组件接收数据的属性设置默认值
withDefaults(defineProps<{
money: number
}>(),{
// 设置默认值 父组件传过来后会覆盖掉
money: 200,
})
// 定义事件,通知父组件修改money的值
const emit = defineEmits<{
// e:'changeMoney'为事件名,固定写法
// money: number 为传给父组件值的类型,不需要传值给父组件可以不写
(e:'changeMoney',money: number): void
}>()
</script>
<template>
<div class="son">
子组件 钱包:{{ money }}元
<!-- 使用事件,点击时通知父组件修改,并将1000传过去 -->
<button @click="emit('changeMoney',1000)">
money+1000
</button>
</div>
</template>
<style scoped>
.son{
width: 300px;
height: 200px;
border: 10px solid black;
}
</style>