当前位置:   article > 正文

Vue + ElementUI 实现全国各个省份相对应城市的联动选择_vue+elementui 省市区联动

vue+elementui 省市区联动

一、需求

做的是一个后台管理系统,这次的项目需求其中一小个是,

对商家门店信息进行添加或者修改编辑时,能选择所在地,包括省份和城市(没有涉及到区县),然后要选择了省份才能选择城市,省份没有选择时不展示城市的选择框,

且选择城市的列表是根据省份来展示相对应的,当更改省份选择时,清空之前选择的城市能进行重新选择城市。

二、效果图

三、具体实现

首先,需要做一些前提准备,在 Vue 项目中通过 npm 安装 ElementUI 组件和 vue-resource 库(实现异步加载时需要使用到的库)

  1. npm i element-ui -S
  2. npm install vue-resource --save-dev

在 main.js 文件中引入

  1. /* 引入 Vue 框架 */
  2. import Vue from 'vue'
  3. /* 引入 ElementUI 组件 */
  4. import ElementUI from 'element-ui'
  5. import 'element-ui/lib/theme-chalk/index.css'
  6. import App from './App.vue'
  7. /* 引入资源请求插件 */
  8. import VueResource from 'vue-resource'
  9. Vue.use(ElementUI)
  10. /* 使用VueResource插件 */
  11. Vue.use(VueResource)

接下来,在 Vue 组件化页面进行开发,使用 ElementUI 组件的 Select 选择器(可清空单选),

这里使用 el-dialog 对话框包含 el-form 表单的结构写法(这不是本次问题的重点,同时省略去掉与此次问题无关的其他表单项),

具体用法参考使用文档:Element - The world's most popular Vue UI framework

  1. <el-dialog
  2. :title="isEdit?'编辑商家门店信息':'添加商家门店信息'"
  3. :visible.sync="modal1"
  4. width="50%">
  5. <el-form :model="merchant"
  6. ref="merchant"
  7. :rules="rules"
  8. label-width="150px">
  9. <el-form-item label="所属省市:" prop="province">
  10. <el-select v-model="merchant.province" placeholder="请选择省份(直辖市)" @change="renderCity" clearable>
  11. <el-option
  12. v-for="item in provinceListAll"
  13. :key="item.name"
  14. :value="item.name">
  15. </el-option>
  16. </el-select>
  17. <el-select v-model="merchant.city" placeholder="请选择城市" v-if="citySelectAble" clearable>
  18. <el-option
  19. v-for="item in cityListAll"
  20. :key="item.name"
  21. :value="item.name">
  22. </el-option>
  23. </el-select>
  24. </el-form-item>
  25. </el-form>
  26. <span slot="footer">
  27. <el-button @click="modal1 = false">取 消</el-button>
  28. <el-button type="primary" @click="handleDialogConfirm('merchant')">确 定</el-button>
  29. </span>
  30. </el-dialog>

定义相对应的数据字段 defaultMerchant (这里同理,与此次问题无关的字段不写入),同时初始化 Vue 实例的数据对象

  1. <script>
  2. const defaultMerchant = {
  3. id: null,
  4. storeName: '', // 门店名称
  5. province: '', // 所属省(直辖市)
  6. city: '', // 所属市
  7. };
  8. export default {
  9. data(){
  10. return{
  11. merchant: Object.assign({}, defaultMerchant),
  12. modal1: false,
  13. isEdit: false,
  14. rules:{ // 用于表单验证的规则
  15. storeName:[{ required: true, message: '请输入商家的门店名称', trigger: 'blur' }],
  16. province:[{ required: true, message: '请输入所属省份(或者直辖市)', trigger: 'blur' }],
  17. },
  18. provinceListAll: [], // 全国34个省份(包括直辖市)列表
  19. cityListAll: [], // 全国各个城市列表
  20. citySelectAble: false, // 城市是否可选
  21. }
  22. },
  23. watch: {},
  24. created() {},
  25. methods: {}
  26. }
  27. </script>

然后要做一个省份列表和城市列表,我看很多小伙伴是把这部分相关数据以 JSON 形式写在页面里或者存在数据库里,这样个人感觉有两点不足吧?一是数据量很大,占用文件很多行数,降低性能和代码的可读性。二是数据不能进行实时更新(假如哪天新多出个城市或者城市改名什么的要去更改内容也麻烦)。这里我的做法是直接调用高德地图的 API 获取省份和城市列表,开发文档可以参考:概述-Web服务 API | 高德地图API

或者参考我的另一篇文章的类似实例 —— vue-resource 的入门学习笔记:vue-resource 的入门学习笔记_无解的菜鸟晖 的博客-CSDN博客

当然开放的平台也有不足,就是需要发送请求,这个每个开发者的 Key 每天有限制请求次数,具体限制查看:流量限制说明-实用工具-开发指南-Web服务 API | 高德地图API

但是,这样请求到的数据比较实时、全面、准确,相比上面的做法会好很多,我们要做的就是减少对 API 的请求,所以可以用数组过滤器来减少请求(提升性能的同时又保证数据的准确性)

  1. methods: {
  2. getAllProvinceAndCityList() { // 获取全国所有省份和城市的列表
  3. var that = this;
  4. this.$http.get('https://restapi.amap.com/v3/config/district',{ // 高德地图的API
  5. params:{
  6. key: this.mapApiKey, // 这个是申请的 Key,读者自行写入
  7. keywords: '中国',
  8. subdistrict: 3,
  9. extensions: 'base'
  10. }
  11. }).then((response) => {
  12. that.provinceListAll = response.data.districts[0].districts;
  13. for (let i = 0; i < response.data.districts[0].districts.length; i++) {
  14. for (let j = 0; j < response.data.districts[0].districts[i].districts.length; j++) {
  15. that.cityListAll.push(response.data.districts[0].districts[i].districts[j]);
  16. }
  17. }
  18. console.log('省份',that.provinceListAll);
  19. console.log('城市',that.cityListAll);
  20. });
  21. },
  22. renderCity() { // 根据选择的省份,展示该省份相对应的城市列表,未选择省份时,不能选择城市
  23. if(this.merchant.province.length > 0) {
  24. this.cityListAll = this.provinceListAll.filter(item => item.name == this.merchant.province)[0].districts;
  25. this.citySelectAble = true;
  26. } else if(!this.merchant.province) {
  27. this.citySelectAble = false;
  28. this.merchant.city = ''; // 清空省份选择时,清空之前选择的城市能进行重新选择城市
  29. }
  30. },
  31. }

这里建议用 console.log() 在控制台输出检查下获取的数据是否正确,然后选择省份组件的值改变时触发 renderCity 函数。当有省份的值时,城市列表用 filter 过滤器选取该省份对应的城市列表,且让城市选择框出现,否则城市选择框不出现。

在页面加载时就要调用请求高德地图 API 的函数,写在 created() 里。同时 watch 监听省份选择,当城市选择后,再次换省份时,能清空已选择的城市。

  1. watch: { // watch 监听 merchant.province,当城市选择后,再次换省份时,能清空已选择的城市
  2. 'merchant.province': function (newValue, oldValue) {
  3. this.merchant.city = '';
  4. }
  5. },
  6. created() { // 页面加载时调用的函数
  7. this.getAllProvinceAndCityList();
  8. },

最后,在每次编辑和添加表单数据时,触发的函数都得调用 renderCity 函数来进行判断,这些函数写在 methods: {} 里:

  1. handleAdd() { // 添加
  2. this.modal1 = true;
  3. this.isEdit = false;
  4. this.merchant = Object.assign({}, defaultMerchant);
  5. this.renderCity();
  6. },
  7. handleUpdate(index, row) { // 编辑
  8. this.modal1 = true;
  9. this.isEdit = true;
  10. this.merchant = Object.assign({},row);
  11. this.renderCity();
  12. },

这是我本人在工作学习中遇到的问题,并对解决问题的方案进行了一次记录,跟小伙伴们分享出来哈 ~ 供参考学习,有什么建议也欢迎评论留言,转载请注明出处哈,感谢支持!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/608427
推荐阅读
相关标签
  

闽ICP备14008679号