在vue中实现省市区的下拉联动
数据是从数据库中得到的,带数据的sql脚本不方便直接粘贴出来,百度一搜也有一大把,我会把创表 sql 粘贴出来地区表创表 sql 如下DROP TABLE IF EXISTS `region`;CREATE TABLE `region`(`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '该地区的自增ID',...
·
数据是从数据库中得到的,带数据的sql脚本不方便直接粘贴出来,百度一搜也有一大把,我会把创表 sql 粘贴出来
地区表创表 sql 如下
DROP TABLE IF EXISTS `region`;
CREATE TABLE `region` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '该地区的自增ID',
`parent_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '该地区的上一个节点的地区id',
`region_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地区名',
`region_type` tinyint(3) UNSIGNED NULL DEFAULT 0 COMMENT '地区的层级',
`is_delete` tinyint(3) UNSIGNED NULL DEFAULT 0 COMMENT '是否删除(0:未删除;1:已删除)',
`region_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '行政区编码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 20593 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统地区表' ROW_FORMAT = Compact;
vue 代码如下
逐个分析
1. 下拉框
<el-select v-model="listQuery.provinceId" placeholder="省级地区" class="filter-item" @change="changeQueryProvince" clearable>
<el-option v-for="(item,index) in provinceList" :key="item.id"
:label="item.regionName" :value="item.id" />
</el-select>
- 由一对 <el-select></el-select>标签包裹多个 <el-option /> 标签组成的下拉框
- v-model:
v-model
的值为当前被选中的el-option
的 value 属性值(会被赋值到下文 data 的 listQuery 对象中的对应属性) - placeholder:占位符,也是没选择时显示的文字
- class:类样式,在本篇博客中没有太重要的意义
- @change:选中值发生变化时触发的事件
- clearable:是否可以清空选项
- v-for:循环遍历 provinceList 集合,每一项别名为 item , 索引为 index
- :key:每一个元素绑定的key值
- :label:选项中显示的内容
- :value:选择后获取的值
2. data
data() {
return {
provinceList: [],
queryCityList: [],
queryRegionList: [],
listQuery: {
provinceId: "",
cityId: "",
regionId: ""
}
};
}
-
provinceList:存放省数据集合
-
queryCityList:存放市数据集合
-
queryRegionList:存放区数据集合
-
listQuery:集合的查询条件
3. methods
// 加载省元数据
getProvince() {
getSystemRegions(0).then(response => {
this.provinceList = response.data.data
})
},
// 改变省
changeQueryProvince() {
this.listQuery.cityId = ''
this.listQuery.regionId = ''
this.queryRegionList = []
if (this.listQuery.provinceId) {
getSystemRegions(this.listQuery.provinceId).then(response => {
this.queryCityList = response.data.data
})
} else {
this.queryCityList = []
}
},
// 改变市
changeQueryCity() {
this.listQuery.regionId = ''
if (this.listQuery.cityId) {
getSystemRegions(this.listQuery.cityId).then(response => {
this.queryRegionList = response.data.data
})
} else {
this.queryRegionList = []
}
}
-
getSystemRegions() 方法通过在 <script></script> 标签内部最上面引入进来的(注:这是引入了 api 中的方法发送的请求,这里三个下拉框调用的是一个 api 接口,都是通过父id(parent_id)来查询数据的,在数据库中,因为省是最上级,所以父 id 为0)
// 引入 api 中的查询方法
import { getSystemRegions } from "@/api/address/address";
//address.js 文件 中的查询 api 方法
export function getSystemRegions(parentId) {
return request({
url: `/getAddress`,
method: 'get',
params: { parentId }
})
}
- 加载省元数据 getProvince() 方法: 调用 api 接口 getSystemRegions() 方法,因为省份是最上级,所以父 id(parent_id)为 0 ,请求成功并返回时,会把数据赋值到 data 的 provinceList(省份集合)中,又因为 vue 的数据是双向绑定的,所以第一个下拉框 v-for 就会遍历出省份的数据,当然,这个获取省份的方法得在页面加载后就自动调用一次
created() {
this.getProvince()
}
- 改变省份 changeQueryProvince() 方法:当省份的下拉框发生改变时(也就是选择了省份的时候),会调用 api 接口 getSystemRegions() 方法,这时,入参的就是选择省份的 id 作为父 id (parent_id)来查询的,请求成功并返回时,会把数据赋值到 data 的 queryCityList(城市集合)中,又因为 vue 的数据是双向绑定的,所以第二个下拉框 v-for 就会遍历出城市的数据,当然,在赋值前会做一些初始化操作(cityId,regionId,queryRegionList 置空)
- 改变城市 changeQueryCity() 方法:与改变省份 changeQueryProvince() 方法类似,根据选择的城市 id 来作为父 id 查询区的数据赋值到 data 的 queryRegionList(区集合)中,因为 vue 的双向绑定,第三个下拉框就是 v-for 遍历出区的数据,操作前也会置空 regionId
4. 还有一点很重要的就是 response.data.data 返回的数据就是本文最上面地区表的一些字段,封装到 List 集合中就可以了
连贯代码
<template>
<div style="padding:20px;">
<el-select v-model="listQuery.provinceId" placeholder="省级地区" class="filter-item"
@change="changeQueryProvince" clearable>
<el-option v-for="(item,index) in provinceList" :key="item.id" :label="item.regionName" :value="item.id"/>
</el-select>
<el-select v-model="listQuery.cityId" placeholder="市级地区" class="filter-item" @change="changeQueryCity" clearable>
<el-option v-for="(item,index) in queryCityList" :key="item.id" :label="item.regionName" :value="item.id" />
</el-select>
<el-select v-model="listQuery.regionId" placeholder="区级地区" class="filter-item" clearable>
<el-option v-for="(item,index) in queryRegionList" :key="item.id" :label="item.regionName" :value="item.id" />
</el-select>
</div>
</template>
<script>
import { getSystemRegions } from "@/api/address/address";
export default {
data() {
return {
provinceList: [],
queryCityList: [],
queryRegionList: [],
listQuery: {
provinceId: "",
cityId: "",
regionId: ""
}
};
},
created() {
this.getProvince()
},
methods: {
// 加载省元数据
getProvince() {
getSystemRegions(0).then(response => {
this.provinceList = response.data.data
})
},
// 改变省
changeQueryProvince() {
this.listQuery.cityId = ''
this.listQuery.regionId = ''
this.queryRegionList = []
if (this.listQuery.provinceId) {
getSystemRegions(this.listQuery.provinceId).then(response => {
this.queryCityList = response.data.data
})
} else {
this.queryCityList = []
}
},
// 改变市
changeQueryCity() {
this.listQuery.regionId = ''
if (this.listQuery.cityId) {
getSystemRegions(this.listQuery.cityId).then(response => {
this.queryRegionList = response.data.data
})
} else {
this.queryRegionList = []
}
},
}
};
</script>
<style>
</style>
如果有朋友需要数据库测试数据,我也可以整一些出来
欢迎来访我的vue专栏总篇博客
希望能够帮助到你
over
更多推荐
已为社区贡献8条内容
所有评论(0)