使用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脚本
Aug 04 Javascript
node.js中的console.trace方法使用说明
Dec 09 Javascript
JS处理json日期格式化问题
Oct 01 Javascript
Javascript实现图片轮播效果(二)图片序列节点的控制实现
Feb 17 Javascript
JS简单实现点击复制链接的方法
Aug 03 Javascript
Backbone中View之间传值的学习心得
Aug 09 Javascript
js实现表单及时验证功能 用户信息立即验证
Sep 13 Javascript
用js实现简单算法的实例代码
Sep 24 Javascript
微信小程序  action-sheet详解及实例代码
Nov 09 Javascript
Vuejs 页面的区域化与组件封装的实现
Sep 11 Javascript
实例分析vue循环列表动态数据的处理方法
Sep 28 Javascript
JS扁平化输出数组的2种方法解析
Sep 17 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
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
2014/07/18 PHP
Ajax提交表单时验证码自动验证 php后端验证码检测
2016/07/20 PHP
PHP面向对象之事务脚本模式(详解)
2017/06/07 PHP
PHP用函数嵌入网站访问量计数器
2017/10/27 PHP
Aster vs Newbee BO5 第二场2.19
2021/03/10 DOTA
用JavaScript显示随机图像或引用
2009/04/21 Javascript
JQuery插件fancybox无法在弹出层使用左右键的解决办法
2013/12/25 Javascript
javaScript 计算两个日期的天数相差(示例代码)
2013/12/27 Javascript
详细介绍jQuery.outerWidth() 函数具体用法
2015/07/20 Javascript
jQuery实现Meizu魅族官方网站的导航菜单效果
2015/09/14 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
2016/02/16 Javascript
jQuery动态添加
2016/04/07 Javascript
jQuery日期范围选择器附源码下载
2017/05/23 jQuery
解决vue.js在编写过程中出现空格不规范报错的问题
2017/09/20 Javascript
vue实现图片预览组件封装与使用
2019/07/13 Javascript
微信小程序button标签open-type属性原理解析
2020/01/21 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
[01:43]深扒TI7聊天轮盘语音出处4
2017/05/11 DOTA
[09:34]2018DOTA2国际邀请赛寻真——永不放弃的iG
2018/08/14 DOTA
Python tempfile模块学习笔记(临时文件)
2014/05/25 Python
介绍Python中内置的itertools模块
2015/04/29 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
使用memory_profiler监测python代码运行时内存消耗方法
2018/12/03 Python
Python 判断奇数偶数的方法
2018/12/20 Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
2019/04/23 Python
解决pycharm remote deployment 配置的问题
2019/06/27 Python
python库matplotlib绘制坐标图
2019/10/18 Python
python列表的逆序遍历实现
2020/04/20 Python
Django怎么在admin后台注册数据库表
2020/11/14 Python
python压包的概念及实例详解
2021/02/17 Python
烹饪大赛策划方案
2014/05/26 职场文书
成绩单评语
2015/01/04 职场文书
领导欢迎词范文
2015/01/26 职场文书
2016年第32个教师节致辞
2015/11/26 职场文书
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
2021/11/27 Vue.js
一文弄懂MySQL中redo log与binlog的区别
2022/02/15 MySQL