所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

多级联动下拉选择框动态获取下一级|超详细前端实现教程新手一看就会

多级联动下拉选择框动态获取下一级|超详细前端实现教程新手一看就会 一

文章目录CloseOpen

第一步:先搞定“数据从哪来”——别再写死数据了!

以前我犯过最傻的错,就是把省市区、商品分类全写成固定数组,比如const provinces = ['广东', '广西', '湖南'],结果朋友说“要加海南省”,我得改代码、重新打包部署,来回折腾半天。后来才明白:动态联动的核心,是“选上一级→发请求拿下一级数据”,而不是把所有数据都塞在代码里。

那数据怎么拿?用Axios或者浏览器原生的Fetch就行——我一般用Axios,因为它比Fetch多了拦截器、错误处理这些方便功能。比如拿省份数据的代码,长这样:

async getProvinces() {

try {

const res = await axios.get('/api/provinces'); // 后端给的省份接口

this.provinceList = res.data; // 把返回的省份列表存到data里

} catch (err) {

alert('省份数据加载失败,换个网试试?'); // 别忘加错误提示,用户不是程序员

}

}

你看,是不是比写死数据灵活多了?就算后端加了新省份,你不用改一行代码——接口返回啥,下拉框就显示啥。

这里有个新手必踩的坑:别忘加async/await!我之前没加这俩关键词,结果请求还没完成,就想给provinceList赋值,页面上啥都没显示,查了半小时才发现是“异步”在搞鬼。记住:只要发请求,就得用async包着函数,await跟着请求——不然数据永远“慢半拍”。

第二步:让“选择”和“数据”联动起来——状态同步是关键

光拿数据还不够,得让“选上一级”的动作,触发“取下一级数据”的操作。这一步的核心是“状态同步”——比如你选了“广东省”(provinceId=1),就得把这个provinceId传给后端,让它返回广东省的城市列表。

我用Vue举个例子(React同理,换useState就行):先在data里定义三个变量——provinceId(选中的省份ID)、cityId(选中的城市ID)、districtId(选中的区县ID),再给省份下拉框加个@change事件,选完省份就触发handleProvinceChange函数:

<!-
  • 模板部分:省份下拉框 >
  • 先选省份呀

    {{ p.name }}

    // methods里的函数:选完省份后做啥?
    

    async handleProvinceChange() {

    // 先清空城市和区县的数据——不然选新省份,旧城市还留着!

    this.cityId = '';

    this.districtId = '';

    this.cityList = [];

    this.districtList = [];

    if (!this.provinceId) return; // 没选省份的话,啥也不做

    try {

    this.isLoading = true; // 加个loading,避免用户点好几次

    const res = await axios.get('/api/cities', {

    params: { province_id: this.provinceId } // 把省份ID传给后端

    });

    this.cityList = res.data; // 把城市列表存起来

    } catch (err) {

    alert('城市数据加载失败,再试一次?');

    } finally {

    this.isLoading = false; // 不管成功失败,都关掉loading

    }

    }

    看见没?选完省份后,我先把城市、区县的ID和列表清空了——这步超重要!我之前没清,结果选了“广东”再选“湖南”,城市列表里还留着“广州”“深圳”,用户以为系统坏了,朋友差点把我骂哭。

    再给你补个避坑技巧:给下一级下拉框加disabled属性!比如城市下拉框,得等选了省份才能点——不然用户没选省份就点城市,只能看见“请选择城市”,体验贼差。代码长这样:

    <!-
  • 城市下拉框:没选省份就禁用 >
  • 选完省份再点我~

    {{ c.name }}

    第三步:踩过的坑全告诉你——新手别再掉进去!

    我做过3个联动下拉框项目,踩了至少5个坑,现在全给你列出来,省得你走弯路:

  • 数据残留:选了“广东”再选“湖南”,城市列表得清空!不然会有旧数据——解决办法就是在handleProvinceChange里,把cityIddistrictIdcityListdistrictList全设为空。
  • 重复请求:用户快速点两次省份,会发两次请求——解决办法是加isLoading状态,请求的时候把isLoading设为true,请求完设为false@change事件里判断isLoadingfalse才发请求。
  • 接口错误没处理:接口挂了,下拉框变成空的,用户不知道咋回事——解决办法是加catch,用alert或者UI组件提示“数据加载失败”。
  • 异步顺序错了:没加async/await,数据慢半拍——记住:发请求就得用这俩关键词!
  • 没做缓存:用户频繁切换省份,每次都发请求,速度慢——解决办法是把请求过的城市数据存到localStorage里,下次直接取:
  • javascript

    const cachedCities = localStorage.getItem(cities_${this.provinceId});

    if (cachedCities) {

    this.cityList = JSON.parse(cachedCities);

    return; // 有缓存就不用发请求了

    }

    // 没缓存的话,再发请求

    const res = await axios.get(‘/api/cities’, { params: { province_id: this.provinceId } });

    this.cityList = res.data;

    localStorage.setItem(cities_${this.provinceId}, JSON.stringify(res.data)); // 存缓存

    最后:给你个能直接跑的Demo——省市区联动照着做就行

    我把省市区联动的核心逻辑整理成了表格,后端需要给你的接口长这样(直接拿给后端看,他秒懂):

    接口地址 请求方式 要传的参数 返回的字段
    /api/provinces GET id(省份ID)、name(省份名称)
    /api/cities GET province_id(省份ID) id(城市ID)、name(城市名称)
    /api/districts GET city_id(城市ID) id(区县ID)、name(区县名称)

    然后把我之前写的Vue代码复制过去,改改接口地址,就能直接跑起来——我去年用这个Demo帮朋友做地址填写功能,他说用户再也没吐槽“选地址麻烦”了。

    其实多级联动下拉框真没那么难,核心就三点:动态拿数据、同步状态、处理细节。我踩过的坑你别踩,我用过的招你直接用——保准你做出来的联动框,比网上那些“复制粘贴”的代码稳多了。

    要是你跟着做的时候遇到问题,或者有啥不懂的地方,评论区留个言——我每天都会看,能帮的肯定帮。毕竟谁没当过“对着下拉框发呆”的新手呢?赶紧去试试吧!


    我之前第一次做联动下拉框的时候,选了省份后城市半天没反应,查了半小时才搞明白——没加async/await啊!那时候我以为发请求就是axios.get一下直接赋值,哪知道请求是“异步”的,就跟你点外卖刚付完钱,转头就站在门口等,外卖员还没出商家门呢,你说能拿到餐吗?后来加上async把函数包起来,前面再挂个await,保证等数据完完整整回来再给cityList赋值, 立马就显示城市了。

    还有次帮朋友调bug,他选省份后城市一直空着,我打开浏览器控制台看请求参数,差点笑出声——后端明明要求传“province_id”,他给写成“provinceId”,就差个下划线!后端接口根本认不出这个参数,自然返回空数据。这就跟你给朋友发消息说“帮我带杯奶菜”,人家肯定一脸懵,不知道你要的是奶茶还是啥奇怪东西。从那以后,我每次传参数前都要对着后端文档念一遍,确认参数名一模一样才敢写,再也没犯过这种低级错。

    最冤的还是没清空旧数据的坑——去年做地址选择功能,我选了广东省,城市列表出来广州、深圳,接着选湖南省,结果城市列表还是广州、深圳!用户截图发过来问“你们系统是不是坏了”,我查代码才发现,handleProvinceChange函数里根本没把cityList设为空数组。就跟你喝奶茶,刚喝完原味的没洗杯子,直接倒珍珠奶茶,喝起来一股混合味儿——后来我学乖了,每次选上一级的时候,第一行代码就是把下一级的ID和列表全清了,cityId设为空,cityList设成空数组,保证新数据能干干净净显示出来。

    现在我遇到选上一级后下一级没数据的情况,第一反应就是查这三点:有没有加async/await?参数名和后端对不对得上?旧数据清没清?基本上80%的问题都能解决,比瞎改代码管用多了——毕竟踩过的坑多了,避坑的经验就熟了嘛。


    Axios和Fetch选哪个更适合新手?

    新手优先选Axios。因为Axios比Fetch多了拦截器(能统一处理请求头、错误)、自带JSON转换(不用手动写res.json()),而且错误处理更直观(catch能直接捕获请求失败)。比如文章里的代码,用Axios只需要await加try/catch,比Fetch少写好几行代码,对新手更友好。

    选上一级后下一级没数据,常见原因有哪些?

    最常见的3个原因:①没加async/await(请求还没完成就想赋值,数据慢半拍);②参数传错了(比如后端要province_id,你传成了provinceId);③没清空旧数据(选新省份后,旧城市数据没清空,导致新数据没显示)。先检查这三点,80%的问题都能解决。

    频繁切换上一级时,请求太多导致加载慢,怎么优化?

    可以加“缓存”和“防抖”。缓存就是把请求过的下一级数据存到localStorage(比如把广东省的城市数据存为cities_1),下次再选广东直接取缓存,不用发请求;防抖是用setTimeout,比如用户1秒内连续点两次省份,只发最后一次请求,避免重复请求。文章里提到的缓存方法,新手直接复制代码就能用,简单有效。

    错误提示除了alert,还有更友好的方式吗?

    当然有。可以用UI组件库的提示功能,比如Element UI的Message、Ant Design的Notification,样式比alert美观,还能自动消失。比如用Element UI的话,把alert换成this.$message.error(‘省份数据加载失败’),用户体验会好很多。如果不用组件库,也可以自己写个带样式的div提示框,比alert更贴合页面风格。

    原文链接:https://www.mayiym.com/45942.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码