Vue3+Vuetify中v-select刷新后不显示选中对象属性的问题
Vue 3.4.31 + Vuetify 3.6.14 下拉选择框刷新后不显示选中值名称问题
环境
- Vue.js 3.4.31
- Vuetify ^3.6.14
需求
从设备对象列表中选择一个设备对象并绑定到模型。
模板代码
<v-select v-model="brModel.equipment" v-if="equipmentsReady" label="设备" :items="equipments" :item-props="equipmentItemProps" item-text="name" // 使用equipmentItemProps效果相同 @update:model-value="oneInputChanged" > </v-select>
Script Setup 代码
const brModel = ref({ id: null, name: null, equipment: null, }) function equipmentItemProps(item) { return { title: item.name } } async function loadEquipments() { try { await axios.get('sanctum/csrf-cookie') const { data } = await axios.get('api/equipments') equipments.value = data.data equipmentsReady.value = true } catch (error) { console.log('加载设备列表出错') } } const equipments = ref() const equipmentsReady = ref(false) loadEquipments() // 加载br数据 loadBr(brId.value) // brId来自请求参数 async function loadBr(id) { try { await axios.get('sanctum/csrf-cookie') const { data } = await axios.get('api/br/' + id) brModel.value = data.data[0] } catch (e) { console.log('加载br数据出错') } }
问题现象
页面刷新时,设备列表正常加载到equipments响应式变量中。选择设备时,v-select能正常绑定选中对象到brModel.equipment并显示设备名称;但页面刷新后,尽管brModel.equipment已经正确加载了对应的设备对象,v-select却不再显示该选中设备的名称,功能仍正常,重新选择后名称能正常显示。
已尝试操作
复制了一个相同的v-select组件,两个组件的选择变更能同步,说明模型绑定是正常的。
疑问
为什么页面刷新(通过接口加载设置模型后),选中设备的名称不再显示?
原因及解决方案
这是因为Vuetify的v-select默认靠对象引用匹配识别选中项。页面刷新后,loadBr接口返回的brModel.equipment是全新的对象实例,和equipments列表里的设备对象引用不相同,所以v-select找不到对应的选项,自然无法显示名称。
有两种可行的解决方法:
方法一:通过唯一标识匹配(推荐)
给v-select添加item-value属性指定设备的唯一字段(比如id),让组件通过字段值而非对象引用来匹配选中项,再配合return-object让v-model返回整个对象:
<v-select v-model="brModel.equipment" v-if="equipmentsReady" label="设备" :items="equipments" item-text="name" item-value="id" return-object @update:model-value="oneInputChanged" > </v-select>
方法二:同步对象引用
加载br数据后,从已加载的equipments列表中找到对应引用的设备对象,替换brModel.equipment:
async function loadBr(id) { try { await axios.get('sanctum/csrf-cookie') const { data } = await axios.get('api/br/' + id) const brData = data.data[0] // 确保equipments已加载完成,再查找对应设备 if (equipments.value) { brData.equipment = equipments.value.find(equip => equip.id === brData.equipment.id) } brModel.value = brData } catch (e) { console.log('加载br数据出错') } }
注意:这种方法需要保证equipments在loadBr执行前已经加载完成,可把loadBr调用放在loadEquipments之后:
// 替换原有的loadBr调用 await loadEquipments() loadBr(brId.value)
内容的提问来源于stack exchange,提问作者Meaulnes
相关产品推荐
相关产品推荐

