在vue中实现省市区的下拉联动

数据是从数据库中得到的,带数据的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

猜你喜欢

转载自blog.csdn.net/qq_41402200/article/details/84939437