使用vue2实现带地区编号和名称的省市县三级联动效果


Posted in Javascript onNovember 05, 2018

我们知道省市区县都有名称和对应的数字唯一编号,使用编号可以更方便查询以及程序处理,我们今天来了解一下使用vue2来实现常见的省市区下拉联动选择效果。

准备数据源

我们的省市区县的数据源来自本站文章 《基于Vue2的简易的省市区县三级联动组件》 中的districts.js,感谢 v-distpicker 作者。districts.js中的数据格式大概是这样的:

export default {
 100000: {
 110000: '北京市',
 120000: '天津市',
 130000: '河北省',
 140000: '山西省',
 ...
 },
 130000: {
 130100: '石家庄市',
 130200: '唐山市',
 130300: '秦皇岛市',
 130400: '邯郸市',
 ...
 },
 130100: {
 130102: '长安区',
 130104: '桥西区',
 130105: '新华区',
 130107: '井陉矿区',
 ...
 },
 ...
}

很显然,districts.js导出的是一个key:value形式的json数据串,那么在js中我们就可以很方便的处理json数据串中的关系。

构建项目

我们使用vue-cli构建项目,需要安装node和vue环境。然后命令行运行: vue init webpack distpicker 构建好项目工程。具体如何操作的请参照vue官网,这些基础的本文不细讲。

现在我们直接编辑App.vue文件。

<template>
 <div id="app" class="container">
 <div class="demo form-inline">
  <select name="province" class="form-control" v-model="province.code" @change="getCitys">
   <option value="">选择省份</option>
   <option v-for="(item, index) in provinceList"
    :value="index"
    :key="index">
   {{ item }}
   </option>
  </select>
  <select name="city" class="form-control" v-show="showcitys" v-model="city.code" @change="getAreas">
   <option value="">选择城市</option>
   <option v-for="(item, index) in cityList"
    :value="index"
    :key="index">
   {{ item }}
   </option>
  </select>
  <select name="area" class="form-control" v-show="showareas" v-model="area.code" @change="getDistValue">
   <option value="">选择区县</option>
   <option v-for="(item, index) in areaList"
    :value="index"
    :key="index">
   {{ item }}
   </option>
  </select>
  <button class="btn btn-info" @click="getSelectVal">获取选中值</button>
  <div style="margin-top:20px;color:red">{{selected}}</div>
 </div>
 </div>
</template>

这是一个简单三个下拉选择器模板,使用 v-model 可以设置默认值, @change 当下拉选择选项后触发的事件。然后每个 select 下的 option 是读取districts.js对应的数据。

JS代码

我们现在来看JS部分,首先使用import导入省市区县数据,注意我们把districts.js文件放在项目的src目录下,然后定义默认编号100000,因为我们第一个(省级)选择框默认要下拉显示所有的省/自治区/直辖市。然后在 data()部分设置变量。最后把 created()methods 部分的代码加上,完整的代码如下:

import DISTRICTS from './districts';
const DEFAULT_CODE = 100000;
export default {
 name: 'App',
 data() {
  return {
   showcitys: false,
   showareas: false,
   selected: '',
   defaultProvince: '湖南省',
   defaultCity: '长沙市',
   defaultArea: '岳麓区',
   province: {},
   city: {},
   area: {},
   provinceList: [],
   cityList: [],
   areaList: []
  }
 },
 created() {
  this.provinceList = this.getDistricts();
  this.getDefault();
 },
 
 methods: {
  getDefault() {
   if (this.defaultProvince !== '') {
    this.showcitys = true;
    let provinceCode = this.getAreaCode(this.defaultProvince);
    this.cityList = this.getDistricts(provinceCode);
    this.province = {
     code: provinceCode,
     value: this.defaultProvince
    }
   }
   
   if (this.defaultCity !== '') {
    this.showareas = true;
    let cityCode = this.getAreaCode(this.defaultCity);
    this.areaList = this.getDistricts(cityCode);
    this.city = {
     code: cityCode,
     value: this.defaultCity
    }
   }
 
   if (this.defaultArea !== '') {
    let areaCode = this.getAreaCode(this.defaultArea);
    this.area = {
     code: areaCode,
     value: this.defaultArea
    }
   }
  },
  getSelectVal() {
   this.selected = this.province.value + this.city.value + this.area.value;
   console.log(this.province.code + '-'+ this.city.code + '-' + this.area.code);
  },
  
  //名称转代码
  nameToCode(name) {
   for(let x in DISTRICTS) {
   for(let y in DISTRICTS[x]) {
    if(name === DISTRICTS[x][y]) {
    return y
    }
   }
   }
  },
  //获取区域代码
  getAreaCode(value) {
   if(typeof value === 'string') {
   return this.nameToCode(value);
   }

   return value;
  },
  
  getCodeValue(code, level=1) {
   if (level == 1) { //省级
    return DISTRICTS[DEFAULT_CODE][code];
    
   } else if (level == 2) {
    let provinceCode = this.province.code;
    return DISTRICTS[provinceCode][code];
  
   } else { //
    let cityCode = this.city.code;
    return DISTRICTS[cityCode][code];
   }
  },
  getDistricts(code = DEFAULT_CODE) {
   return DISTRICTS[code] || []
  },
  
  cleanList(name) {
   this[name] = []
  },
  getCitys(e) {
   this.cityList = this.getDistricts(e.target.value);

   this.cleanList('areas')
   this.province = this.setData(e.target.value, 1);
   this.areaList = [];
   this.showareas = false;
   this.showcitys = true;
  },
  getAreas (e) {
   this.areaList = this.getDistricts(e.target.value);
   this.city = this.setData(e.target.value, 2);
   this.showareas = true;
  },
  getDistValue (e) {
   this.area = this.setData(e.target.value, 3);
  },
  setData(code, level = 1) {
   code = parseInt(code);
   return {
    code: code,
    value: this.getCodeValue(code, level),
   }
  },

 }
}

运行

我们需要实现的效果是:默认显示省级下拉选择框,下拉选项中应该默认载入省级名称,然后当选择省级下拉框中的省份列表(省级)选项时,显示选中省份的城市列表(市级),然后选择市级城市选项,显示选择城市的区县列表(县级)。在选择完每个选项时,我们应该即时记录选项对应的编号和名称。如果在 data() 部分设置了省市区县的默认值,则三个下拉框都要显示。

运行 npm run dev ,在浏览器中输入http://localhost:8080查看效果。

效果是实现了,但是如果要在一个页面调用多个三级联动效果则就比较尴尬了,下节我给大家讲述如何把这个三级联动效果封装成vue组件,造好轮子,方便在更多地方调用,敬请关注。

总结

以上所述是小编给大家介绍的使用vue2实现带地区编号和名称的省市县三级联动效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript EXCEL 操作类代码
Jul 30 Javascript
JavaScript初学者需要了解10个小技巧
Aug 25 Javascript
JS声明变量背后的编译原理剖析
Dec 28 Javascript
textarea 控制输入字符字节数(示例代码)
Dec 27 Javascript
关于JS数组追加数组采用push.apply的问题
Jun 09 Javascript
jQuery实现带延迟的二级tab切换下拉列表效果
Sep 01 Javascript
1秒50万字!js实现关键词匹配
Aug 01 Javascript
详解webpack进阶之loader篇
Aug 23 Javascript
页面缩放兼容性处理方法(zoom,Firefox火狐浏览器)
Aug 29 Javascript
element-ui 设置菜单栏展开的方法
Aug 22 Javascript
对于防止按钮重复点击的尝试详解
Apr 22 Javascript
基于vue中的scoped坑点解说
Sep 04 Javascript
vue router的基本使用和配置教程
Nov 05 #Javascript
微信小程序tabbar底部导航
Nov 05 #Javascript
详解webpack+ES6+Sass搭建多页面应用
Nov 05 #Javascript
浅谈vux之x-input使用以及源码解读
Nov 04 #Javascript
小程序实现选择题选择效果
Nov 04 #Javascript
小程序实现单选多选功能
Nov 04 #Javascript
Vuex的基本概念、项目搭建以及入坑点
Nov 04 #Javascript
You might like
打造计数器DIY三步曲(下)
2006/10/09 PHP
有关 PHP 和 MySQL 时区的一点总结
2008/03/26 PHP
学习使用curl采集curl使用方法
2012/01/11 PHP
php中可能用来加密字符串的函数[base64_encode、urlencode、sha1]
2012/01/16 PHP
smarty基础之拼接字符串的详解
2013/06/18 PHP
使用PHP Socket 编程模拟Http post和get请求
2014/11/25 PHP
laravel 框架实现无限级分类的方法示例
2019/10/31 PHP
PHP中的输出echo、print、printf、sprintf、print_r和var_dump的示例代码
2020/12/01 PHP
在JavaScript中获取请求的URL参数
2010/12/22 Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
2011/03/10 Javascript
javascript-简单的计算器实现步骤分解(附图)
2013/05/30 Javascript
关于JavaScript命名空间的一些心得
2014/06/07 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
2016/06/08 Javascript
AngularJS中$http使用的简单介绍
2017/03/17 Javascript
layui中layer前端组件实现图片显示功能的方法分析
2017/10/13 Javascript
在Bootstrap开发框架中使用dataTable直接录入表格行数据的方法
2018/10/25 Javascript
在vue项目中优雅的使用SVG的方法实例详解
2018/12/03 Javascript
vue 点击其他区域关闭自定义div操作
2020/07/17 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
[02:30]联想杯DOTA2完美世界全国高校联赛—北京站现场
2015/11/16 DOTA
[45:16]完美世界DOTA2联赛循环赛 IO vs FTD BO2第二场 11.05
2020/11/06 DOTA
详解python里使用正则表达式的分组命名方式
2017/10/24 Python
python实现字符串和字典的转换
2018/09/29 Python
CSS3 box-sizing属性
2009/04/17 HTML / CSS
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
美国电子元器件分销商:Newark element14
2018/01/13 全球购物
艺术用品:Arteza
2018/11/25 全球购物
技术学校毕业生求职信分享
2013/12/02 职场文书
教师档案管理制度
2014/01/23 职场文书
集体婚礼策划方案
2014/02/22 职场文书
文秘求职信范文
2014/04/10 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
2014年个人总结范文
2015/03/09 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书
2016年寒假政治学习心得体会
2015/10/09 职场文书
nginx常用配置conf的示例代码详解
2022/03/21 Servers