实现效果如图:
<template>
<!-- 地区选择-->
<div class="distpicker" @click.stop>
<div class="input-text" :class="{selectActive:multistageFlag}" @click="toSelectArea">
<div>
<span>{
{country}}</span>
<span>{
{province}}</span>
<span>{
{city}}</span>
</div>
<span class="select-icon icon icon-arrow-down" :class="{iconActive:multistageFlag}"></span>
</div>
<div class="multistage" v-if="multistageFlag">
<div class="options country-options" v-show="countryFlag">
<ul>
<li class="select-options" v-for="(cony,index) in areaList" :key="index"
:class="{active:country === cony.name}"
@click="selectCountry(cony.id, true)">
<span>{
{cony.name}}</span>
<span v-if="cony.children.length>0" class="icon icon-fanhui"></span>
</li>
</ul>
</div>
<div class="options province-options" v-show="provinceFlag">
<label class="search-field">
<input type="text" v-model.trim="searchProvince" @keyup.enter="toSearchProvince"
placeholder="请输入搜索内容" autofocus>
<span class="icon icon-search" @click="toSearchProvince"></span>
</label>
<ul>
<li class="select-options" v-for="(pro,index) in provinceList" :key="index"
:class="{active:province === pro.name}"
@click="selectProvince(pro.id, true)">
<span>{
{pro.name}}</span>
<span v-if="pro.children.length>0" class="icon icon-fanhui"></span>
</li>
</ul>
</div>
<div class="options city-options" v-if="cityFlag">
<label class="search-field">
<input type="text" v-model.trim="searchCity" @keyup.enter="toSearchCity"
placeholder="请输入搜索内容" autofocus>
<span class="icon icon-search" @click="toSearchCity"></span>
</label>
<ul>
<li class="select-options" v-for="(cty,index) in cityList" :key="index"
:class="{active:city === cty.name}"
@click="selectCity(cty.id)">
<span>{
{cty.name}}</span>
</li>
</ul>
</div>
</div>
<div class="btn-wrapper" v-if="btnFlag">
<button class="btn btn-md btn-theme-border" @click="selectResult(1)" :disable="country===''">取消</button>
<button class="btn btn-md btn-theme" @click="selectResult(2)" :disable="country===''">确定</button>
</div>
</div>
</template>
<script>
export default {
name: 'regionalLinkage',
data() {
return {
multistageFlag:false,//多级联动显隐
country: '不限',//国家
province:'',//省份
city:'',//城市
// areaList:[
// {name: '不限',id:'', children:[]},
// {
// name:'中国', id:'中国',
// children:[
// {
// name:'四川',id:'四川', parentId:'中国',
// children:[
// {name:'凉山',id:'凉山',parentId:'四川'},
// {name:'资阳',id:'资阳',parentId:'四川'},
// {name:'成都',id:'成都',parentId:'四川'},
// ]
// },
// {
// name:'重庆',id:'重庆',
// children:[
// {name:'酉阳',id:'酉阳',parentId:'重庆'},
// {name:'彭水',id:'彭水',parentId:'重庆'},
// ]
// },
// {
// name:'陕西', id:'陕西',
// children:[
// {name:'商洛',id:'商洛',parentId:'陕西'},
// {name:'西安',id:'西安',parentId:'陕西'},
// ]
// }
// ]
// }
// ],
countryFlag:false,//国家list显隐
provinceList:[],//省份list
provinceFlag:false,//省份list显隐
cityList:[],//城市list
cityFlag:false,//城市list显隐
searchProvince:'',//搜索省份
searchCity:'',//搜索城市
currentArea: {}
};
},
component: {},
watch: {},
props:{
areaList:{//城市列表
type:Array
},
lastAreaSelect:{//父组件回传子组件上次选中的地区
type:Object,
default:{
country:'',
province:'',
city:''
}
},
btnFlag:{//底部按钮显隐
type:Boolean,
default: false
}
},
mounted() {
if (this.lastAreaSelect.country != '' && this.lastAreaSelect.country != undefined) {
this.country = this.lastAreaSelect.country;
this.province = this.lastAreaSelect.province;
this.city = this.lastAreaSelect.city;
this.selectCountry(this.lastAreaSelect.country, true);
this.selectProvince(this.lastAreaSelect.province, true);
this.selectCity(this.lastAreaSelect.city);
}
//点击其他地方下拉菜单收起
window.addEventListener('click', this.eventListener);
},
destroyed() {
window.removeEventListener('click', this.eventListener);
},
methods: {
toSelectArea() {
this.currentArea = {
country:this.country,
province:this.province,
city:this.city
};
this.multistageFlag = !this.multistageFlag;
this.countryFlag = true;
this.searchCity = '';
this.searchProvince = '';
this.selectCountry(this.currentArea.country, true);
this.selectProvince(this.currentArea.province, true);
this.selectCity(this.currentArea.city);
},
/**
* 选择国家
* toEmpty 是否清空搜索关键字 true清空 false不清空
* */
selectCountry(country, toEmpty) {
if (toEmpty) {
this.searchProvince = '';
}
if (country === '') {
this.country = '不限';
} else {
this.country = country;
}
this.provinceList = [];
for (let i = 0; i < this.areaList.length; i++) {
if (this.areaList[i].id === country) {
this.provinceList = this.areaList[i].children;
}
}
if (this.provinceList.length === 0) {
this.provinceFlag = false;
} else {
this.provinceFlag = true;
}
this.cityFlag = false;
this.province = '';
this.city = '';
},
//选择省份
selectProvince(province, toEmpty) {
if (toEmpty) {
this.searchCity = '';
}
this.province = province;
this.cityList = [];
for (let i = 0; i < this.provinceList.length; i++) {
if (this.provinceList[i].id === province) {
this.cityList = this.provinceList[i].children;
}
}
if (this.cityList.length === 0) {
this.cityFlag = false;
} else {
this.cityFlag = true;
}
this.city = '';
},
//选择城市
selectCity(city) {
this.city = city;
},
/**
* 地区选择结果
* @param type 1取消选择 2确定选择
*/
selectResult(type){
if (type === 1) {
//取消
this.cityFlag = false;
this.provinceFlag = false;
this.city = '';
this.province = '';
this.country = '不限';
}
this.$emit('sureAreaSelect',{country:this.country, province:this.province, city:this.city});
this.searchCity = '';
this.searchProvince = '';
},
//搜索省份
toSearchProvince(){
this.selectCountry(this.country, false);
let keyList = [];
this.provinceList.forEach((item) => {
let key = item.id;
if (key.indexOf(this.searchProvince) != -1) {
keyList.push(item);
}
});
this.provinceList = keyList;
},
//搜索城市
toSearchCity() {
this.selectProvince(this.province, false);
let keyList = [];
this.cityList.forEach((item) => {
let key = item.id;
if (key.indexOf(this.searchCity) != -1) {
keyList.push(item);
}
});
this.cityList = keyList;
},
//通用方法 下拉菜单的收起
eventListener() {
this.multistageFlag = false;
this.searchCity = '';
this.searchProvince = '';
},
}
};
</script>
<style type="text/scss" lang="scss">
@import '../../../common/scss/base/variables';
@import '../../../common/scss/base/mixin';
.drop-list{
padding: 5px;
}
.distpicker{
width: 100%;
.input-text{
width: 200px;
display: flex;
justify-content: space-between;
background-color: #fff;
padding: 0 5px;
border-radius: 3px;
border: 1px solid $border-color;
&.selectActive{
border-color: $green;
}
.select-icon{
&.iconActive{
color: $green;
}
}
}
.multistage{
display: flex;
.options{
border: 1px solid $border-color;
background-color: #fff;
min-width: 210px;
flex-shrink: 1;
.select-options{
display: flex;
justify-content: space-between;
cursor: pointer;
padding: 0 5px;
&.active{
background-color: $select-bg;
}
}
.search-field {
position: relative;
display: flex;
align-items: center;
height: $input-field-height;
border-bottom: 1px solid $select-border;
background-color: $title-bg;
@include border-radius(0);
color: $color-light-content;
input {
height: $input-field-height;
padding: 0 8px 0 28px;
width: 100%;
min-width: 5em; // 否则placeholder显示不全
border: none;
background-color: transparent;
&:hover {
background-color: $select-bg;
& + .icon-search {
background-color: $select-bg;
}
}
&:focus {
background-color: #fff;
& + .icon-search {
background-color: #fff;
}
}
}
.icon-search {
$offset: ($input-field-height - 14px) / 2;
position: absolute;
width: 26px;
height: $input-field-height - 2px;
line-height: $input-field-height;
text-align: center;
left: 1px;
top: 1px;
background-color: transparent;
}
}
}
}
.btn-wrapper{
display: flex;
margin: 5px 0;
justify-content: flex-end;
}
}
</style>