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

学习笔记 2018/11/07 jQuery

准备数据源

我们的省市区县的数据源来自本站文章《基于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文件。

选择省份{{ item }}选择城市{{ item }}选择区县{{ item }}获取选中值{{selected}}

这是一个简单三个下拉选择器模板,使用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组件,造好轮子,方便在更多地方调用,敬请关注。

本文地址:https://www.stayed.cn/item/110

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。