You need to enable JavaScript to run this app. Vue.js 中实现州-城市级联下拉选及城市加载失败问题排查
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js 中实现州-城市级联下拉选及城市加载失败问题排查

联动下拉失效问题修复方案

核心失效原因

  • 最关键的bug:listCities方法调用接口拿到响应后,没有把返回的城市列表赋值给组件的cities响应式变量,导致下拉框始终绑定空数组,自然没有可选选项
  • 缺少切州时的重置逻辑:切换州时没有清空之前选中的城市值和旧城市列表,容易残留跨州的无效选中值
  • 缺少交互兜底:未选州时城市下拉没有禁用态,也没有占位提示,用户体验割裂
  • 城市请求没有对齐已有的错误处理逻辑,接口异常时无反馈

修正实现步骤

  1. 补全listCities方法的响应赋值逻辑,对齐listStates的错误处理流程
  2. 触发州切换事件时,先清空旧的城市列表、重置城市选中值,避免脏数据
  3. 增加前置判断:未选中州时直接中断城市请求,不发送无效查询
  4. 优化下拉框交互:未选州时城市下拉置灰禁用,增加加载提示和默认占位选项

修正后的脚本代码

export default {
  data() {
    return {
      loading: false,
      inscription: new InscriptionModel(),
      successful: false,
      message: '',
      arrProfiles: [],
      arrStatus: [],
      states: [],
      cities: [],
    };
  },
  async mounted() {
    this.states = await this.listStates();
  },
  methods: {
    async listStates() {
      const response = await api.post('graphql', {
        query: `
          query{
            listStates{ data { id, name, uf } }
          }
        `,
      });
      if (Helpers.hasProperty(response.data, 'errors')) {
        Helpers.getValidateException(response.data);
        return;
      }
      return response.data.data.listStates.data;
    },
    async listCities() {
      // 切换州时先重置旧数据
      this.cities = []
      this.inscription.cities = ''
      // 未选中州直接终止请求
      if (!this.inscription.state) return

      this.loading = true
      try {
        const response = await api.post('graphql', {
          query: `
            query{
              listCities(condition: {state_id: ${this.inscription.state}})
              { data { id, name } }
            }
          `,
        });
        // 对齐已有错误处理逻辑
        if (Helpers.hasProperty(response.data, 'errors')) {
          Helpers.getValidateException(response.data);
          return;
        }
        // 关键:将接口返回的城市列表赋值给响应式变量,驱动下拉渲染
        this.cities = response.data.data.listCities.data
      } finally {
        this.loading = false
      }
    }
  }
}

修正后的模板代码

<div class="col-sm-12 col-md-6 col-lg-3 col-xl-3">
  <div class="form-group">
    <label for="state_id">State</label>
    <select 
      name="state" 
      id="state_id" 
      class="custom-select" 
      @change="listCities()" 
      v-model="inscription.state"
    >
      <option value="" disabled>请选择州</option>
      <option v-for="state in states" v-bind:value="state.id" :key="state.id">
        {{ state.name }}
      </option>
    </select>
  </div>
</div>

<div class="col-sm-12 col-md-6 col-lg-3 col-xl-3">
  <div class="form-group">
    <label for="city_id">City</label>
    <select 
      id="citie" 
      v-model="inscription.cities" 
      class="custom-select"
      :disabled="!inscription.state"
    >
      <option value="" disabled>{{ loading ? '城市加载中...' : '请先选择州' }}</option>
      <option v-for="citie in cities" v-bind:value="citie.id" :key="citie.id">
        {{ citie.name }}
      </option>
    </select>
  </div>
</div>

内容的提问来源于stack exchange,提问作者testCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.06 01:15:04