在我的父组件中我有类似的东西,
<template>
<ProductCounter v-model="formData.productCount" label="product count" />
</template>
<script setup>
const initialFormData = {
productCount: null,
firstname: '',
surname: '',
phone: '',
email: '',
postcode: '',
submittedOnce: false,
errors: []
}
let formData = reactive({ ...initialFormData });
const clearUI = () => {
formData = reactive({ ...initialFormData });
triggerInlineForm.value = false;
}
</script>
我的子组件看起来像这样,
<template>
<div class="form__row" @reset-counts="resetCount">
<div class="counter__row">
<label>{{ label }}</label>
<div class="form__counter">
<button class="form__button--decrease form__button--circle form__button--animate-scale" :disabled="value == 0 || props.disabled" @click.prevent="decreaseCount()">
<i>
<FontAwesomeIcon :icon="['fal', 'minus']" />
</i>
</button>
<input type="text" v-model="value" :disabled="props.disabled" @input="updateQty" placeholder="0"/>
<button class="form__button--increase form__button--circle form__button--animate-scale" :disabled="props.disabled" @click.prevent="increaseCount()">
<i>
<FontAwesomeIcon :icon="['fal', 'plus']" />
</i>
</button>
</div>
</div>
</div>
</template>
<script setup>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
const emits = defineEmits(['update:modelValue', 'resetCounts']);
const props = defineProps({
label: {
type: String,
required: true
},
modelValue: {
type: String,
required: true,
default: 0
},
disabled: {
type: Boolean,
required: false
}
});
const value = ref(props.modelValue);
const updateQty = () => {
emits('update:modelValue', value.value)
}
const increaseCount = () => {
value.value++
emits('update:modelValue', value.value)
}
const decreaseCount = () => {
value.value--;
emits('update:modelValue', value.value)
}
</script>
我希望当从父级触发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>