Vue.js获取select选中id通过axios post实现级联下拉框
问题根因
你当前的代码无法生效核心是两个逻辑错误:
- 生命周期执行时机不对:
mounted是组件挂载完成后仅执行一次的钩子,触发时用户还未操作第一个下拉选择框,selectedMark还是初始值null,此时直接发起车型请求自然拿不到正确参数。 - 下拉框取值逻辑错误:你没有给第一个select的
<option>标签绑定value属性,此时v-model绑定的selectedMark存的是option标签内的文本(也就是品牌名称),而非你需要的品牌id。
可行解决方案
按以下两步修改代码即可实现级联选择效果:
- 给第一个下拉框的option绑定
:value="model.id",让选中时selectedMark直接存储选中项的id - 移除
mounted中写死的车型请求,改用watch监听selectedMark的变化,当用户选中品牌、id更新后再发起车型接口请求
修改后的完整代码如下:
模板部分
<main class="home-page"> <select v-model="selectedMark"> <!-- 绑定value为品牌id,选中时selectedMark会直接拿到id值 --> <option v-for="model in items" :key="model.id" :value="model.id">{{ model.name.value }}</option> </select><br><br> <select v-model="selectedModel"> <option v-for="make in info" :key="make.id" >{{ make.name.value }}</option> </select><br><br> <button type="submit" class="conectButton">Połącz</button> <div class="titleCarMain"><p class="titleCar">{{selectedMark}}</p><p class="titleComponent">{{selectedModel}}</p></div> </main>
脚本部分
import axios from 'axios'; export default { name: "App", data() { return { info: [], // 初始值改为空数组,避免v-for遍历null时报错 items: [], selectedMark: null, selectedModel: null, }; }, watch: { // 监听选中品牌id的变化 async selectedMark(newBrandId) { // 未选中品牌时清空车型列表和已选值,不发起请求 if (!newBrandId) { this.info = [] this.selectedModel = null return } // 拿到最新的品牌id后请求对应车型列表 const res = await axios.post("http://local/api/sd/model/get", { id: newBrandId }) this.info = res.data.data.items // 切换品牌后重置车型选中状态,避免选项和选中值不匹配 this.selectedModel = null } }, async mounted() { // mounted阶段只需要拉取第一个下拉框的品牌列表即可 const res = await axios.get("http://local/api/sd/make/get") this.items = res.data.data.items }, };
原理说明
- Vue的
v-model在select标签上使用时,会自动将选中option的value属性值绑定到对应变量上,未手动绑定value时默认取option的文本内容,因此必须显式绑定id作为value才能拿到需要的请求参数。 mounted生命周期仅在组件第一次渲染到页面后触发1次,无法捕获用户后续的交互操作产生的值变化,不适合处理依赖用户输入的动态请求。watch监听器会在被监听的变量值发生更新时自动触发回调,回调可以拿到变量的最新值,是实现级联选择、联动请求这类场景的标准方案。- 切换品牌时重置车型选中值、初始化info为空数组,是为了避免下拉选项和选中状态不匹配、渲染报错的边界问题。
内容的提问来源于stack exchange,提问作者Okatawo
相关产品推荐
相关产品推荐

