在Web开发中,省市区城市三级联动选择是非常常见的功能。本文将介绍如何使用jQuery和Layui框架来制作这样一个下拉框城市选择效果,并且可以获取选中的城市数据。

准备工作

需要引入jQuery和Layui框架的相关文件。可以通过CDN或者下载后本地引用。

<!-- 引入jQuery -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<!-- 引入Layui的CSS文件 -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/layui.min.css">

<!-- 引入Layui的JS文件 -->
<script src="https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/layui.all.min.js"></script>

HTML结构

在HTML中,我们需要创建一个输入框和一个按钮来触发选择城市的功能。还需要在HTML中添加下拉框的容器,用于显示省市区城市三级联动的菜单。

<!-- 输入框 -->
<input type="text" id="city-picker-input" readonly>

<!-- 按钮 -->
<button id="city-picker-btn">选择城市</button>

<!-- 下拉框容器 -->
<div id="city-picker-container"></div>

JavaScript代码

就需要编写JavaScript代码了。我们需要初始化Layui的form模块和citys数据。

// 初始化layui的form模块
layui.use(['form'], function() {
    var form = layui.form;
});

// 城市数据
var citys = [{
    "code": "110000",
    "name": "北京市",
    "sub": [{
        "code": "110100",
        "name": "市辖区",
        "sub": [{
            "code": "110101",
            "name": "东城区"
        }, {
            "code": "110102",
            "name": "西城区"
        }, {
            "code": "110105",
            "name": "朝阳区"
        }, {
            "code": "110106",
            "name": "丰台区"
        }, {
            "code": "110107",
            "name": "石景山区"
        }, {
            "code": "110108",
            "name": "海淀区"
        }, {
            "code": "110109",
            "name": "门头沟区"
        }, {
            "code": "110111",
            "name": "房山区"
        }, {
            "code": "110112",
            "name": "通州区"
        }, {
            "code": "110113",
            "name": "顺义区"
        }, {
            "code": "110114",
            "name": "昌平区"
        }, {
            "code": "110115",
            "name": "大兴区"
        }, {
            "code": "110116",
            "name": "怀柔区"
        }, {
            "code": "110117",
            "name": "平谷区"
        }]
    }, {
        "code": "110200",
        "name": "县",
        "sub": [{
            "code": "110228",
            "name": "密云县"
        }, {
            "code": "110229",
            "name": "延庆县"
        }]
    }]
}, {
    "code": "120000",
    "name": "天津市",
    "sub": [{
        "code": "120100",
        "name": "市辖区",
        "sub": [{
            "code": "120101",
            "name": "和平区"
        }, {
            "code": "120102",
            "name": "河东区"
        }, {
            "code": "120103",
            "name": "河西区"
        }, {
            "code": "120104",
            "name": "南开区"
        }, {
            "code": "120105",
            "name": "河北区"
        }, {
            "code": "120106",
		"name": "红桥区"
		}, {
		"code": "120110",
		"name": "东丽区"
		}, {
		"code": "120111",
		"name": "西青区"
		}, {
		"code": "120112",
		"name": "津南区"
		}, {
		"code": "120113",
		"name": "北辰区"
		}, {
		"code": "120114",
		"name": "武清区"
		}, {
		"code": "120115",
		"name": "宝坻区"
		}, {
		"code": "120116",
		"name": "滨海新区"
		}]
		}, {
		"code": "120200",
		"name": "县",
		"sub": [{
		"code": "120221",
		"name": "宁河县"
		}, {
		"code": "120223",
		"name": "静海县"
		}, {
		"code": "120225",
		"name": "蓟县"
		}]
		}]
		}, {
		"code": "130000",
		"name": "河北省",
		"sub": [{
		"code": "130100",
		"name": "石家庄市",
		"sub": [{
		"code": "130102",
		"name": "长安区"
		}, {
		"code": "130104",
		"name": "桥西区"
		}, {
		"code": "130105",
		"name": "新华区"
		}, {
		"code": "130107",
		"name": "井陉矿区"
		}, {
		"code": "130108",
		"name": "裕华区"
		}, {
		"code": "130109",
		"name": "藁城区"
		}, {
		"code": "130110",
		"name": "鹿泉区"
		}, {
		"code": "130111",
		"name": "栾城区"
		}, {
		"code": "130121",
		"name": "井陉县"
		}, {
		"code": "130123",
		"name": "正定县"
		}, {
		"code": "130125",
		"name": "行唐县"
		}, {
		"code": "130126",
		"name": "灵寿县"
		}, {
		"code": "130127",
		"name": "高邑县"
		}, {
		"code": "130128",
		"name": "深泽县"
		}, {
		"code": "130129",
		"name": "赞皇县"
		}, {
		"code": "130130",
		"name": "无极县"
		}, {
		"code": "130131",
		"name": "平山县"
		}, {
		"code": "130132",
		"name": "元氏县"
		}, {
		"code": "130133",
		"name": "赵县"
		}, {
		"code": "130183",
		"name": "晋州市"
		}, {
		"code": "130184",
		"name": "新乐市"
		}]
		}, {
		"code": "130200",
		"name": "唐山市",
		"sub": [{
		"code": "130202",
		"name": "路南区"
		}, {
		"code": "130203",
		"name": "路北区"
		}, {
		"code": "130204",
		"name": "古冶区"
		}, {
		"code": "130205",
		"name": "开平区"
		}]
	}]
}];

我们可以编写一个函数用于生成省市区城市三级联动的菜单,并将其添加到下拉框容器中。

// 生成省市区城市三级联动菜单
function generateCityPicker() {
    // 获取省级数据
    var provinces = citys.map(function(item) {
        return {
            code: item.code,
            name: item.name
        };
    });

    // 获取市级数据和区县级数据
    var cities = {};
    var areas = {};
    $.each(citys, function(index, province) {
        if(!province.sub) {
			return;
		}
		var provinceCode = province.code;
		var provinceName = province.name;
		var provinceCities = province.sub.map(function(city) {
			return {
				code: city.code,
				name: city.name
			};
		});
		cities[provinceCode] = provinceCities;
		
		 $.each(province.sub, function(index, city) {
			if (!city.sub) {
				return;
			}
			var cityCode = city.code;
			var cityAreas = city.sub.map(function(area) {
				return {
					code: area.code,
					name: area.name
				};
			});
        	areas[cityCode] = cityAreas;
		});
	});

	// 生成菜单
	var tpl = '<div class="layui-inline"><select name="{name}" lay-filter="{filter}"><option value="">请选择</option>{options}</select></div>';
	var html = '';
	html += tpl.replace('{name}', 'province').replace('{filter}', 'province').replace('{options}', provinces.map(function(item) {
		return '<option value="' + item.code + '">' + item.name + '</option>';
	}).join(''));
	html += tpl.replace('{name}', 'city').replace('{filter}', 'city').replace('{options}', '<option value="">请选择</option>');
	html += tpl.replace('{name}', 'area').replace('{filter}', 'area').replace('{options}', '<option value="">请选择</option>');
	
	$('#city-picker-container').html(html);
	
	// 绑定事件
	layui.form.on('select(province)', function(data) {
		var code = data.value;
		var cityHtml = '<option value="">请选择</option>';
		if (code) {
			var cityList = cities[code];
			if (cityList && cityList.length > 0) {
				cityHtml += cityList.map(function(item) {
					return '<option value="' + item.code + '">' + item.name + '</option>';
				}).join('');
			}
		}
		$('#city-picker-container select[name=city]').html(cityHtml);
		layui.form.render('select');
	});

	layui.form.on('select(city)', function(data) {
		var code = data.value;
		var areaHtml = '<option value="">请选择</option>';
		if (code) {
			var areaList = areas[code];
			if (areaList && areaList.length > 0) {
				areaHtml += areaList.map(function(item) {
					return '<option value="' + item.code + '">' + item.name + '</option>';
				}).join('');
			}
		}
		$('#city-picker-container select[name=area]').html(areaHtml);
		layui.form.render('select');
	});
}

我们可以编写一个函数用于显示下拉框城市选择效果,并且获取选中的城市数据。

// 显示下拉框城市选择效果
function showCityPicker() {
    generateCityPicker();

    // 弹出层
    layer.open({
        type: 1,
        title: '选择城市',
        content: $('#city-picker-container'),
        area: ['600px', 'auto'],
        btn: ['确定', '取消'],
        yes: function(index, layero) {
            var provinceCode = $('#city-picker-container select[name=province]').val();
            var cityCode = $('#city-picker-container select[name=city]').val();
            var areaCode = $('#city-picker-container select[name=area]').val();
            var provinceName = $('#city-picker-container select[name=province] option:selected').text();
            var cityName = $('#city-picker-container select[name=city] option:selected').text();
            var areaName = $('#city-picker-container select[name=area] option:selected').text();
            var cityData = {
                province: {
                    code: provinceCode,
                    name: provinceName
                },
                city: {
                    code: cityCode,
                    name: cityName
                },
                area: {
                    code: areaCode,
                    name: areaName
                }
            };
            $('#city-picker-input').val(provinceName + ' ' + cityName + ' ' + areaName);
            layer.close(index);
        },
        btn2: function(index, layero) {
            layer.close(index);
        }
    });
}

在按钮点击事件中调用showCityPicker函数即可。

// 按钮点击事件
$('#city-picker-btn').on('click', function() {
    showCityPicker();
});

至此,我们就完成了省市区城市三级联动菜单选择的功能。

本文介绍了如何使用jQuery和Layui框架来制作常用的省市区城市三级联动菜单选择器。通过解析JSON格式的省市区数据,生成相应的下拉框菜单,并且绑定相关的事件来实现联动效果。在弹出层中获取选中的城市数据并展示到文本框中。这种做法可以应用于各种需要选择省市区城市的场景,比如用户注册、商品配送等等。