Vue3更新ref后复选框组组件未同步选中状态问题
问题:Vue3 + Bootstrap-Vue复选框组无法同步选中状态
使用Vue3结合Bootstrap-Vue实现表单,包含三个文本输入框和一个复选框组。调用API获取默认值后,文本输入框能正常更新,但复选框组存在问题:即便目标选项值已在tagList数组中,对应复选框仍未被选中。
问题代码分析
父组件组合式函数代码
// 定义表单数据ref const formValues = ref<IArticleFormValues>({ title: '', body: '', description: '', tagList: [], }); // useQuery获取API数据 const { data, isFetching } = useQuery({ queryKey: ['fetchArticleBySlug', slug], queryFn: () => fetchSingleArticleService(slug) }); // 监听API数据更新表单 watch(data, () => { if (data.value?.article) { formValues.value = { ...data.value.article, tagList: data.value.article.tagList.map((item) => item), }; } }); // 注入表单数据 provide(formInjectionKey, { formValues });
复选框组使用代码
<script setup lang="ts"> import CustomCheckboxGroup from '@/components/DesignSystem/components/CustomCheckboxGroup.vue'; import { inject } from 'vue'; const { formValues } = inject(formInjectionKey); </script> <template> <CustomCheckboxGroup v-else :options="tags" v-model="formValues.tagList" /> </template>
注:tags格式为[{text:'example',value:'example'}],tagList格式为['example']
CustomCheckboxGroup组件代码
<script setup lang="ts"> defineProps<{ value?: any[]; options: any[] }>(); </script> <template> <b-form-group> <b-form-checkbox-group :value="value" @input="$emit('input', $event)" :options="options" v-bind="$attrs" stacked ></b-form-checkbox-group> </b-form-group> </template>
解决方案
1. 修正CustomCheckboxGroup的v-model绑定逻辑
Vue3中组件的v-model默认基于modelValue prop和update:modelValue事件,而非Vue2的value和input。需要调整CustomCheckboxGroup组件的定义:
<script setup lang="ts"> defineProps<{ modelValue?: any[]; options: any[] }>(); defineEmits<{ 'update:modelValue': [value: any[]] }>(); </script> <template> <b-form-group> <b-form-checkbox-group :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)" :options="options" v-bind="$attrs" stacked ></b-form-checkbox-group> </b-form-group> </template>
说明:Bootstrap-Vue的b-form-checkbox-group本身支持Vue3的v-model语法,直接绑定model-value和监听update:model-value事件即可正确同步选中状态。
2. 确保响应式更新的稳定性
虽然直接替换formValues.value对象是可行的,但可以通过逐个赋值的方式避免潜在的响应式丢失问题(可选优化):
watch(data, () => { if (data.value?.article) { const article = data.value.article; formValues.value.title = article.title; formValues.value.body = article.body; formValues.value.description = article.description; // 直接替换数组确保响应式 formValues.value.tagList = [...article.tagList]; } });
3. 验证选项匹配逻辑
确认tags数组中的value字段与tagList中的值完全匹配(类型、字符串大小写一致)。例如:
- 如果
tagList中的值是字符串'example',则tags中的选项必须包含{text:'example',value:'example'},不能出现类型不匹配(如数字与字符串)或大小写差异。
内容的提问来源于stack exchange,提问作者alirezafarin
相关产品推荐
相关产品推荐

