在我的父组件中我有类似的东西,
我的子组件看起来像这样,
我希望当从父级触发clearUI并且formData被重置时,ProductCounter的v模型应该反映返回到0,但事实并非如此,我哪里出错了?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
实时解决方案的链接
请下次在 https://play.vuejs.org/ 上准备最低限度的可重现示例。对于你的问题:
请不要覆盖 Vue 中的响应式变量...
只需改变它们
Object.assign(formData,initialFormData):也不要取消引用组件属性:
const value = ref(props.modelValue)。这些属性失去了它们的反应性,因为您只是复制了一个原始值。创建
v-model模式的最佳方法是使用计算,您可以直接在模板中操作它。const value = computed({ get(){ return props.modelValue; }, set(val){ emits('update:modelValue', val); } });此外,您的 count 属性应该是数字,而不是字符串(您会收到 Vue 警告):
modelValue: { type: Number, required: true, default: 0 },此外,无需更新
input事件上的 prop,因为您已经在上使用v-model>。您还应该将输入的模型转换为数字:所以你有: 应用程序视图
<template> <p> <ProductCounter v-model="formData.productCount" label="product count" /> </p> <button @click="clearUI"> Clear </button> <div> {{ JSON.stringify(formData) }} </div> </template> <script setup> import ProductCounter from './ProductCounter.vue' import {reactive} from 'vue' const initialFormData = { productCount: 0, firstname: '', surname: '', phone: '', email: '', postcode: '', submittedOnce: false, errors: [] } let formData = reactive({ ...initialFormData }); const clearUI = () => { Object.assign(formData, initialFormData); } </script>ProductCounter.vue:
<template> <div class="form__row"> <div class="counter__row"> <label>{{ label }}</label> <div class="form__counter"> <button :disabled="value == 0 || props.disabled" @click.prevent="value--"> - </button> <input type="text" v-model.number="value" :disabled="props.disabled" placeholder="0"/> <button :disabled="props.disabled" @click.prevent="value++"> + </button> </div> </div> </div> </template> <script setup> import {computed} from 'vue'; const emits = defineEmits(['update:modelValue']); const props = defineProps({ label: { type: String, required: true }, modelValue: { type: Number, required: true, default: 0 }, disabled: { type: Boolean, required: false } }); const value = computed({ get(){ return props.modelValue; }, set(val){ emits('update:modelValue', val); } }); </script>