一、效果
二、实现思路
1、准备中国所有省、市、县的数据源;
2、准备三个下拉框A(省)、B(市)、C(县),三个下拉框存在联动关系,
即:A下拉框选择省份之后,B下拉框中被填充A对应的城市名;
B下拉框选择城市之后,C下拉框中被填充B对应的县名;
3、城市选择器对外提供的数据:当前三个下拉框选择的数据;
4、城市选择器接受外界传入的值:
【1】省、市、县的数据,用于给城市选择器赋值;
【2】id,为了区分在同一个页面中多处使用的城市选择器;
三、代码分析
1、数据格式
//获取部分数据,表示省级、市级、县级
module.exports = [...
{
"code": "650000",//当前省市的区号编码
"sheng": "65",//省的标示符,同一个省的地区此字段相等
"di": "00",//市级的标示符,同一个市的地区此字段相等
"xian": "00",//县级、区标示符
"name": "新疆维吾尔自治区",//地区名称
"level": 1 /*级别:1-省;2-市;3-区、县城*/
},
{
"code": "652700",
"sheng": "65",
"di": "27",
"xian": "00",
"name": "博尔塔拉蒙古自治州",
"level": 2
},
{
"code": "652722",
"sheng": "65",
"di": "27",
"xian": "22",
"name": "精河县",
"level": 3
}...]
说明:
全国的省份、市级、县级的数据存放于assets文件夹中的JS文件。通过module.exports对外界提供接口;
使用方法:import provinceData from "./assets/..."导入数据;
2、dom代码
<template>
<div class="cityselect">
/*省级下拉框*/
<select :id="selectItems_province.id" class="form-control"
:name="selectItems_province.name" v-model="selectedProvince" v-on:change="complete">
<option :value="i.name" v-for="i in selectItems_province.data" v-text="i.name"></option>
</select>
/*市级下拉框*/
<select :id="selectItems_city.id" class="form-control"
:name="selectItems_city.name" v-model="selectedCity" v-on:change="complete">
<option :value="i.name" v-for="i in selectItems_city.data" v-text="i.name"></option>
</select>
/*县级、区下拉框*/
<select :id="selectItems_block.id" class="form-control"
:name="selectItems_block.name" v-model="selectedBlock" v-on:change="complete">
<option :value="i.name" v-for="i in selectItems_block.data" v-text="i.name"></option>
</select>
</div>
</template>
3、data代码
................
data(){
return {
/*省级下拉框框的id、name、下拉框中的数据*/
selectItems_province:
{
id:"province_select",
name:"province",
data :[]
},
/*市级下拉框框的id、name、下拉框中的数据*/
selectItems_city:
{
id:"city_select",
name:"city",
data:[]
},
/*县级下拉框框的id、name、下拉框中的数据*/
selectItems_block:
{
id:"block_select",
name:"block",
data :[]
},
selectedProvince:"",//下拉框当前选择的省
selectedCity:"",//下拉框当前选择的市
selectedBlock:"",//下拉框当前选择的县
allProvince:[],//存放下拉框的所有省份
allCity:[],//存放当前下拉框的省份对应的所有城市
allBlock:[],//存放当前下拉框的城市对应的所有县、区
//判断是给select赋值还是选择。true-选择;false-赋值
//因为选择下拉框时,会置空后面的下拉框,赋值时不会。
isSelect:true
}
}
.........
4、生命周期-mounted
说明:mounted生命周期中,dom已经生成。
mounted(){
let _this = this;
/*获取省级、市级、县级数据*/
_this.getSelectItems();
}
5、methods中的方法
/*把省份、城市、县级区分开*/
getSelectItems(){
let _this = this;
//获取所有城市的数据
let len = provinces.length;
//数据处理:区分出省、市、县/区
for(let i=0;i<len;i++){
switch (provinces[i].level){
case 1:
{
_this.allProvince.push(provinces[i]);
break;
}
case 2:
{
_this.allCity.push(provinces[i]);
break;
}
case 3:
{
_this.allBlock.push(provinces[i]);
break;
}
default:{
break;
}
}
}
//向下拉框存入省份
_this.selectItems_province.data = [].concat(_this.allProvince);
}
/*
*每次下拉框改变值之后调用此方法
*获取组件选择的省份、市级、县级的值
*/
complete(){
let _this = this;
//设置当前是选择的状态
_this.isSelect = true;
let dataObj = {
provice: _this.selectedProvince,
city:_this.selectedCity,
block : _this.selectedBlock
};
//向父级组件传入选择的省、市、县
this.$emit("getSelectData",dataObj);
},
/*获取父级传递的数据(省、市、县)*/
getParentData(){
let _this = this;
_this.isSelect = false;
//由于vue组件传值的单向数据流,所以由父级向子级传入的值需要重新赋值变量,否则会报错
_this.selectedProvince = this.sour.provice;
_this.selectedCity = this.sour.city;
_this.selectedBlock = this.sour.block;
}
6、watch数据监听
/*监听省份的数据变化*/
selectedProvince(newData,oldData){
let _this = this;
//获取所有省级数据
let len_allProvince = _this.allProvince.length;
//获取所有市级数据
let len_allCity = _this.allCity.length;
let provinceObj = {};
/*置空市级、县级下拉框中的数据*/
_this.selectItems_city.data = [];
_this.selectItems_block.data = [];
if(_this.isSelect){
/*选择时需要置空市级、县级选择框*/
_this.selectedCity = "";
_this.selectedBlock = "";
}
//通过当前选择的省份,在所有省份里找到对应省份数据对象
for(let i =0;i<len_allProvince;i++){
if(newData == _this.allProvince[i].name){
provinceObj = _this.allProvince[i];
break;
}
}
//通过省份的对象,在所有城市里找到对应省份下的城市
for(let j=0;j<len_allCity;j++){
if(_this.allCity[j].sheng == provinceObj.sheng){
_this.selectItems_city.data.push(_this.allCity[j]);
}
}
},
/*监听市级的数据变化*/
selectedCity(newData,oldData){
let _this = this;
let len_allCity = _this.allCity.length;
let len_allBlock = _this.allBlock.length;
let cityObj = {};
/*置空县级*/
_this.selectItems_block.data = [];
if(_this.isSelect){
/*选择时需要置空县级选择框*/
_this.selectedBlock = "";
}
/*在全部城市的数组中,获取当前选择的城市数据对象*/
for(let i =0;i<len_allCity;i++){
if(newData == _this.allCity[i].name){
cityObj = _this.allCity[i];
}
}
/*通过当前市级数据,查询其下的县级*/
for(let j=0;j<len_allBlock;j++){
if(_this.allBlock[j].sheng ==cityObj.sheng
&& _this.allBlock[j].di == cityObj.di){
_this.selectItems_block.data.push(_this.allBlock[j]);
}
}
},
/*监听父级传递过来的数据,实时接受父级传入的值*/
sour(){
this.getParentData();
}
7、父子组件通信
/*
* 父级--》子级 传值
*/
props:{
/*父级传入{省,市级,县级}*/
sour:{
type:Object,//传入的数据对象
default(){
return {};//默认值
}
}
}
/*
* 子级--》父级 传值
*/
complete(){
let _this = this;
_this.isSelect = true;
let dataObj = {
provice: _this.selectedProvince,
city:_this.selectedCity,
block : _this.selectedBlock
};
//通过$emit向父级传值,
//第一个参数,声明getSelectData方法;
//第二参数:传入父级的数据(作为getSelectData的参数进行传递)
_this.$emit("getSelectData",dataObj);
}
eg:
<cityselect :sour="editCmdData.sour" v-on:getSelectData = "selectData"></cityselect>
:sour--》向子级传入的值
v-on:getSelectData --》通过getSelectData接受子级传入父级的值
四、Git路径
待定。。。。。。