一、背景和意义
在vue
开发中,时常会涉及到子组件之间传递数据。经典的方法是使用props
和emit
,而vue 3.4+
提供的defineModel
方法可以用更少的代码实现这一功能。本文提供一个defineModel
方法实现子组件间传递数据的示例。
二、经典方法实现子组件间传递数据
经典方法是使用props
与emit
,父组件代码如下:
html
<template>
<div>
<h1>value in parent: {{transferValue}}</h1>
<ChildA :transferValue="transferValue" @changeValue="handleChangeValue"/>
<ChildB :transferValue="transferValue" />
</div>
</template>
<script setup>
import { ref } from "vue";
const transferValue = ref("Hello");
const handleChangeValue = newVal => {
transferValue.value = newVal;
};
</script>
子组件ChildA.vue
的代码如下:
html
<template>
<div>
<h1>value in ChildA: {{transferValue}}</h1>
<button @click="changeValue">change value by childA</button>
</div>
</template>
<script setup>
defineProps({
transferValue: ""
});
const emits = defineEmits(['changeValue']);
const changeValue = () => {
emits("changeValue", "hello2");
};
</script>
子组件ChildB.vue
的代码如下:
html
<template>
<div>
<h1>value in ChildB: {{transferValue}}</h1>
<h1>value length in ChildB: {{valueLength}}</h1>
</div>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
transferValue: ""
});
const valueLength = computed(() => {
return props.transferValue?.length || 0;
});
</script>
运行效果如下:
点击子组件ChildA
的change value by childA
按钮之后,父组件和两个子组件的数据均发生了变化。
三、实现子组件间传递数据
使用defineModel
需要3.4及以上的vue
版本。父组件改为:
html
<template>
<div>
<h1>value in parent: {{transferValue}}</h1>
<ChildA v-model="transferValue"/>
<ChildB v-model="transferValue" />
</div>
</template>
<script setup>
import { ref } from "vue"
const transferValue = ref("Hello");
</script>
子组件ChildA
改为:
html
<template>
<div>
<h1>value in ChildA: {{transferValue}}</h1>
<button @click="changeValue">change value by childA</button>
</div>
</template>
<script setup>
const transferValue = defineModel();
const changeValue = () => {
transferValue.value = "hello2";
};
</script>
子组件ChildB
改为:
html
<template>
<div>
<h1>value in ChildB: {{transferValue}}</h1>
<h1>value length in ChildB: {{valueLength}}</h1>
</div>
</template>
<script setup>
import { computed } from "vue";
const transferValue = defineModel();
const valueLength = computed(() => {
return transferValue?.value?.length || 0;
});
</script>
程序运行效果和前面经典方法的效果一样,但新的defineModel
方法代码更少。