vue3中父子组件数据同步的默认方式update:xxx
update:xxx 是Vue 3中实现自定义v-model的约定。它的工作原理是:
子组件通过emit('update:propName', newValue)通知父组件需要更新某个属性
父组件可以通过v-model:propName="data"或@update:propName="data = $event"来接收这个更新
父组件:
<template>
<div class="container">
<CountShow :count="count"></CountShow>
<CountUpdate :count="count" @update:count="count = $event"></CountUpdate>
</div>
</template>
<script setup>
import { ref } from 'vue'
import CountShow from "./CountShow.vue"
import CountUpdate from "./CountUpdate.vue"
const count = ref(0)
</script>
<style scoped>
.container {
margin-top: 20px;
}
</style>
子组件:
<template>
<select v-model.number="step">
<option value=1 selected>1</option>
<option value=2>2</option>
<option value=3>3</option>
</select>
<button @click="increaseCount">增加</button>
<button @click="decreaseCount">减少</button>
<button @click="oddIncreaseCount">奇数增加</button>
<button @click="asyncIncreaseCount">异步增加(延迟1秒)</button>
</template>
<script setup>
import { ref, computed } from 'vue'
const props = defineProps({
count: {
type: Number,
default: 0
}
})
const step = ref(1)
const emit = defineEmits(['update:count'])
const increaseCount = () => {
emit('update:count', props.count + step.value)
}
const decreaseCount = () => {
emit('update:count', props.count - step.value)
}
const oddIncreaseCount = () => {
if (props.count % 2 === 1) {
emit('update:count', props.count + step.value)
}
}
const asyncIncreaseCount = async () => {
await new Promise(resolve => setTimeout(resolve, 1000))
emit('update:count', props.count + step.value)
}
</script>
思考:上面是把数据count放在父组件中,更新数据count的功能按钮放在了子组件中。那么,如果把更新数据的功能也放在父组件中呢?
如下:
父组件
<template>
<div class="container">
<CountShow :count="count"></CountShow>
<CountUpdate @increase="handleIncrease" @decrease="handleDecrease" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import CountShow from "@/components/counter/CountShow.vue"
import CountUpdate from "@/components/counter/CountUpdate.vue"
const count = ref(0)
// 父组件中的更新函数
defineExpose({
handleIncrease: (step) => {
count.value += step
},
handleDecrease: (step) => {
count.value -= step
}
})
</script>
子组件:
<template>
<div>
<select v-model.number="step">
<!-- 选项不变 -->
</select>
<button @click="$emit('increase', step.value)">增加</button>
<button @click="$emit('decrease', step.value)">减少</button>//$emit又是一种触发事件的用法
<!-- 其他按钮类似修改 -->
</div>
</template>
<script setup>
import { ref } from 'vue'
const step = ref(0)
defineEmits(['increase', 'decrease', 'oddIncrease', 'asyncIncrease'])
</script>

浙公网安备 33010602011771号