项目中需要用到三级联动选择省份+城市。因项目中已用到swiper组件,遂选择了swiper来做三级联动功能,避免重复赘余,节省代码量。话不多说,直接上代码。如有不明白的地方,可留言。看到会回复的,望对诸位有所帮助。
1.安装swiper
npm install vue-awesome-swiper --save
2.组件(SelectAddress.vue)
<template>
<transition name="fade">
<section class="picker-container">
<div class="picker-shade"></div>
<div class="picker-wrapper">
<div class="picker-top-bar">
<div class="picker-cancel" @click="cancel">取消</div>
<h2 class="picker-tit">所在地区</h2>
<div class="picker-confirm" @click="confirm">确认</div>
</div>
<div class="picker-content">
<div class="center-highlight"></div>
<swiper :options="swiperOption">
<swiper-slide v-for="(item, index) in provinceList" :key="index">{{item.provinceName}}</swiper-slide>
</swiper>
<swiper :options="swiperOption2">
<swiper-slide v-for="(item, index) in cityList" :key="index">{{item.cityName}}</swiper-slide>
</swiper>
</div>
</div>
</section>
</transition>
</template>
<script>
import service from '../../api/service.js'
export default {
data() {
let that = this;
return {
isFirst: true,
swiperOption: {
slidesPerView: 'auto',
centeredSlides: true,
direction: 'vertical',
on: {
slideChangeTransitionEnd: function(){
that.provinceID = that.provinceList[this.activeIndex].provinceID;
that.provinceName = that.provinceList[this.activeIndex].provinceName;
that.getCityList();
}
}
},
provinceList: [],
provinceID: '',
provinceName: '',
swiperOption2: {
slidesPerView: 'auto',
centeredSlides: true,
direction: 'vertical',
on: {
slideChangeTransitionEnd: function(){
that.cityID = that.cityList[this.activeIndex].cityID;
that.cityName = that.cityList[this.activeIndex].cityName;
}
}
},
cityList: [],
cityID: '',
cityName: '',
}
},
methods: {
//请求省份列表
getProvinceList(){
service.getProvinceList({
countryId: 1
}).then(res => {
if (res.code == '0') {
this.provinceList = res.data;
this.provinceID = res.data[0].provinceID;
this.provinceName = res.data[0].provinceName;
this.getCityList();
}
})
},
getCityList(){
//请求城市列表
service.getCityList({
provinceID: this.provinceID
}).then(res => {
if (res.code == '0') {
this.cityList = res.data;
this.cityID = res.data[0].cityID;
this.cityName = res.data[0].cityName;
}
})
},
confirm(){
var addressInfo = {
provinceId: this.provinceID,
provinceName: this.provinceName,
cityId: this.cityID,
cityName: this.cityName,
};
this.$emit("confirm", addressInfo);
},
cancel(){
this.$emit("cancel");
}
},
created(){
this.getProvinceList();
},
mounted(){
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
/* 仿ios select选择 */
.picker-container { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 10; font-size: 30px; background-color: rgba(0,0,0,0.5); }
.picker-shade { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
.picker-wrapper { position: absolute; left: 0; bottom: 0; width: 100%; z-index: 1; background-color: #fff; }
.picker-container.active .picker-shade { background-color: rgba(0,0,0,.5); }
.picker-container.active .picker-wrapper { -webkit-transform: translate3d(0,0,0); }
.picker-top-bar { background-color:#f3f3f3; text-align: center; color: #fff; font-size: 0.375rem; }
.picker-top-bar h2 {font-size: 0.375rem; height: 92px; line-height: 92px; color: #919191; }
.picker-tit { margin: 0 1.5625rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.picker-cancel,
.picker-confirm { position: absolute; top: 0; width: 1.5625rem; font-size: 0.375rem; line-height: 92px;color:black; }
.picker-cancel { left: 0; }
.picker-confirm { right: 0; }
.picker-content { position: relative; display: flex; width: 90%; padding: 30px 0; margin: 0 auto; -webkit-mask-box-image: linear-gradient(to top, transparent, transparent 5%, white 20%, white 80%, transparent 95%, transparent); text-align: center; }
.picker-content .swiper-container { flex: 1; height: 4.6875rem; }
.picker-content .center-highlight { height: 70px; position: absolute; left: 0; width: 100%; top: 50%; margin-top: -35px; border-top: 1px solid #dcdcdc; border-bottom: 1px solid #dcdcdc; pointer-events: none; }
.picker-content .swiper-slide { height: 70px; line-height: 70px; font-size: 0.40625rem;color:gray; }
.picker-content .swiper-slide-active { font-size: 0.46875rem; color: #d0a358;}
</style>
3.父组件引用SelectAddress子组件
<template>
<div class="wrap">
<div class="flex-mid line" @click="addressSelect">
<span>城市</span>
<input type="text" readonly="readonly" v-model="area" class="input-right" />
</div>
<select-address v-if="addressShow" v-on:confirm="addressSelectConfirm" v-on:cancel="addressSelectCancel"></select-address>
</div>
</template>
<script>
import SelectAddress from './common/SelectAddress'; //引入
export default {
components: {
SelectAddress
},
data() {
return {
//城市选择
area: '',
provinceId: '',
provinceName: '',
cityId: '',
cityName: '',
addressShow: false,
}
},
methods: {
addressSelect(){
this.addressShow = true;
},
addressSelectCancel(){
this.addressShow = false;
},
addressSelectConfirm(info){
this.provinceId = info.provinceId;
this.provinceName = info.provinceName;
this.cityId = info.cityId;
this.cityName = info.cityName;
this.area = info.provinceName+" "+info.cityName;
this.addressShow = false;
}
}
}