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>

 

posted @ 2025-09-12 15:47  充实地生活着  阅读(23)  评论(0)    收藏  举报