Vue.js中select下拉框无法回显数据库返回的contact_id选中值
问题描述
Vue.js项目开发中遇到异常:从数据库获取的contact_id值无法在select下拉选择框中显示为已选中状态。
以下是select下拉框的实现代码:
<form @submit.prevent="updateProject" method="put" autocomplete="off"> <select id="select" v-model="form.project.contact_id" class="form-select" required> <option v-for="contact in contacts" :key="contact.id" :selected="contact.id == 14">{{ contact.name }}</option> </select> <input type="text" class="form-control" placeholder="Enter Project Name" v-model="form.project.project_name"> </form>
以下是对应script逻辑代码:
<script> export default { data() { return { projectId: this.$route.params.id, contacts: [], showSelectedInjection: false, form: { project: {}, contact: [], }, } }, mounted: function () { this.getProjectDetails(); this.initialData(); }, methods: { initialData() { this.$axios.$get("/api/projects/initial-data") .then(function (response) { this.contacts = response; }.bind(this)); }, getProjectDetails() { this.$axios.$get('/api/projects/' + this.projectId + '/edit') .then(response => { this.form.project = response; console.log(this.form.project); }) .catch(error => { this.$toast.error("Error fetching contact details"); }); }, updateProject() { this.$axios.$put('/api/projects/' + this.projectId , this.form) .then(response => { this.$toast.success("Project Updated Successfully"); }) .catch(error => { this.$toast.error("Error updating sale"); }); } } } </script>
相关说明
项目数据表存储字段包含contact_id、项目名称、预算、开始日期、结束日期。调用接口获取项目详情后,通过console.log打印this.form.project得到的返回数据结构如下:
{"id":1,"project_name":"website","budget":"10000","start_date_time":"2022-06-08","end_date_time":"2022-06-14","location":"jdfj","contact_id":1,"contract_id":null,"created_at":"2022-06-14T20:29:53.000000Z","updated_at":"2022-06-14T20:29:53.000000Z"}
返回数据中contact_id字段值正常存在,需要实现将该contact_id对应的下拉选项设置为select框的默认选中项。
故障原因
- select标签绑定
v-model="form.project.contact_id"时,Vue的v-model双向绑定逻辑优先级高于原生selected属性,手动写在option上的:selected绑定会被v-model覆盖。现有代码硬编码:selected="contact.id == 14"既不满足动态匹配需求,本身也无法正常生效。 getProjectDetails和initialData两个接口在mounted钩子中并发执行,存在异步竞态问题:如果联系人下拉列表contacts还未加载完成,form.project.contact_id就完成赋值,v-model找不到匹配对应值的option节点,会导致选中状态失效。- 遍历生成的option标签未绑定
value属性,v-model无法建立绑定值和下拉选项的映射关系,无法自动匹配选中项。
修复方案
- 移除option上冗余的
:selected绑定,给每个option绑定和contact_id对应的value值,v-model会自动根据绑定值匹配选中项,修改后的select代码如下:
<select id="select" v-model="form.project.contact_id" class="form-select" required> <option v-for="contact in contacts" :key="contact.id" :value="contact.id">{{ contact.name }}</option> </select>
- 解决异步竞态问题,调整接口调用顺序,等联系人下拉选项加载完成后,再拉取项目详情给
contact_id赋值,保证v-model赋值时下拉选项已经完成渲染。修改mounted和initialData逻辑如下:
mounted: async function () { // 先加载联系人下拉选项 await this.initialData(); // 选项加载完成后再拉取项目详情 this.getProjectDetails(); }, methods: { initialData() { // 返回promise供await调用 return this.$axios.$get("/api/projects/initial-data") .then(function (response) { this.contacts = response; }.bind(this)); }, // 其余方法逻辑保持不变即可 }
- 校验数据类型一致性:如果接口返回的
contact.id和form.project.contact_id类型不统一(比如一个是字符串、一个是数字),会因为全等匹配失败导致选不中,这种情况在绑定value或赋值时统一类型即可,例如:value="String(contact.id)"。
修复完成后,只要v-model绑定的
contact_id和option的value值完全相等、选项渲染先于赋值完成,下拉框就会自动显示对应选中项。
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

