☰
js三级联动功能详解
2026/10/19 4:16:14 网站建设 项目流程

省市区三级联动

一句话总结:选择省 → 自动加载对应省下的市;选择市 → 自动加载对应市下的区,层层筛选,上一级改变,下一级选项自动更新。

✅ 解决什么问题

  1. 地址选择时,一次性加载全国所有省市区几万条数据,数据量大,渲染慢、浪费内存。
  2. 手动选择地址容易选错、省市区不匹配(选河南,城市却出现广州)。
  3. 简化地址录入,提升用户体验,保证提交后端的数据是合法对应的省、市、区编码。

两种实现方案: ①前端版三级联动:一次性把全部省市区 JSON 数据拿到前端,JS 筛选(作业最常用) ②后端接口版:选省份,请求接口拿该省的市;选市,请求拿区(真实项目)

✅ 应用场景

  1. 收货地址填写(电商、会员信息)
  2. 后台表单录入:客户地址、企业注册地址(你的新乡企业项目大概率会用到)
  3. 地区筛选:按省市区筛选数据列表

✅ 怎么使用(前端 JSON 版本,作业首选,用 let、箭头函数)

HTML 结构

<!-- 三个下拉框 select --> <select id="province"> <option value="">请选择省份</option> </select> <select id="city"> <option value="">请选择城市</option> </select> <select id="area"> <option value="">请选择区县</option> </select>

JS 完整代码

// 模拟省市区数据源,真实项目会引入完整的省市区json文件 let areaData = [ { code: '410000', name: '河南省', children: [ { code: '410700', name: '新乡市', children: [ {code:'410702',name:'红旗区'}, {code:'410703',name:'卫滨区'}, {code:'410704',name:'凤泉区'} ] }, { code: '410100', name: '郑州市', children: [ {code:'410102',name:'中原区'}, {code:'410103',name:'二七区'} ] } ] }, { code: '110000', name: '北京市', children: [ { code: '110100', name: '北京市', children: [ {code:'110101',name:'东城区'}, {code:'110102',name:'西城区'} ] } ] } ] // 获取三个下拉框DOM let provinceSel = document.querySelector('#province'); let citySel = document.querySelector('#city'); let areaSel = document.querySelector('#area'); // 渲染省份下拉 let renderProvince = ()=>{ let html = '<option value="">请选择省份</option>'; areaData.forEach(item=>{ html += `<option value="${item.code}">${item.name}</option>` }) provinceSel.innerHTML = html; } // 根据省份code,渲染市 let renderCity = (provCode)=>{ // 清空市、区下拉 citySel.innerHTML = '<option value="">请选择城市</option>'; areaSel.innerHTML = '<option value="">请选择区县</option>'; // 找到选中的省份 let targetProvince = areaData.find(item=> item.code === provCode); if(!targetProvince) return; let html = ''; targetProvince.children.forEach(city=>{ html += `<option value="${city.code}">${city.name}</option>` }) citySel.innerHTML = html; } // 根据市code,渲染区 let renderArea = (cityCode)=>{ areaSel.innerHTML = '<option value="">请选择区县</option>'; // 遍历找城市 let targetCity = null; for(let p of areaData){ targetCity = p.children.find(c=> c.code === cityCode); if(targetCity) break; } if(!targetCity) return; let html = ''; targetCity.children.forEach(area=>{ html += `<option value="${area.code}">${area.name}</option>` }) areaSel.innerHTML = html; } // 省份切换事件 provinceSel.addEventListener('change', (e)=>{ let provCode = e.target.value; renderCity(provCode); }) // 城市切换事件 citySel.addEventListener('change',(e)=>{ let cityCode = e.target.value; renderArea(cityCode); }) // 页面加载初始化省份 renderProvince();

后端接口版本(企业真实项目)

逻辑:不一次性加载全部数据

  1. 页面初始化:请求接口拿到所有省份,渲染省份下拉
  2. 选中省份 → 把省份 code 传给后端接口,返回该省的所有市,渲染市下拉
  3. 选中市 → 把市 code 传给后端接口,返回该市的所有区县,渲染区下拉

优点:不用一次性加载巨大的省市区 JSON,节省带宽,适合线上项目 缺点:每次切换都要发请求

// 省份改变,请求城市 provinceSel.addEventListener('change', async (e)=>{ let provCode = e.target.value; // 请求接口获取城市列表 let res = await fetch(`/api/getCity?provCode=${provCode}`) let cityList = await res.json(); // 渲染城市下拉 })

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询