Files
yshopb2c-uniapp/components/CitySelect.vue

326 lines
8.5 KiB
Vue
Raw Normal View History

2020-07-12 22:44:37 +08:00
<template>
<view>
2021-11-07 23:51:59 +08:00
<text class="uni-input" @tap="open">{{ value }}</text>
2020-07-12 22:44:37 +08:00
<uni-popup ref="popup" type="bottom">
<view class="cityselect">
<view class="cityselect-header">
<view class="cityselect-title">
<text>请选择地址</text>
</view>
<view class="cityselect-nav">
<view class="item" v-if="provinceActive" @tap="changeNav(0)">
2021-11-07 23:51:59 +08:00
<text>{{ provinceActive.n }}</text>
2020-07-12 22:44:37 +08:00
</view>
<view class="item" v-if="cityActive" @tap="changeNav(1)">
2021-11-07 23:51:59 +08:00
<text>{{ cityActive.n }}</text>
2020-07-12 22:44:37 +08:00
</view>
<view class="item" v-if="districtActive" @tap="changeNav(2)">
2021-11-07 23:51:59 +08:00
<text>{{ districtActive.n }}</text>
2020-07-12 22:44:37 +08:00
</view>
<view class="item active" v-else>
<text>请选择</text>
</view>
</view>
</view>
<view class="cityselect-content">
<swiper class="swiper" disable-touch="true" touchable="false" :current="current">
<swiper-item>
<scroll-view scroll-y class="cityScroll">
<view>
2021-11-07 23:51:59 +08:00
<view class="cityselect-item" v-for="(item, index) in province" :key="index" @tap="selectProvince(index)">
<view class="cityselect-item-box" :class="{ active: isProvinceActive(item) }">
<text>{{ item.n }}</text>
2020-07-12 22:44:37 +08:00
</view>
</view>
</view>
</scroll-view>
</swiper-item>
<swiper-item>
<scroll-view scroll-y class="cityScroll">
<view>
2021-11-07 23:51:59 +08:00
<view class="cityselect-item" v-for="(item, index) in city" :key="index" @tap="selectCity(index)">
<view class="cityselect-item-box" :class="{ active: isCityActive(item)}">
<text>{{ item.n }}</text>
2020-07-12 22:44:37 +08:00
</view>
</view>
</view>
</scroll-view>
</swiper-item>
<swiper-item>
<scroll-view scroll-y class="cityScroll">
<view>
2021-11-07 23:51:59 +08:00
<view class="cityselect-item" v-for="(item, index) in district" :key="index" @tap="selectDistrict(index)">
<view class="cityselect-item-box" :class="{ active: isDistrictActive(item) }">
<text>{{ item.n }}</text>
2020-07-12 22:44:37 +08:00
</view>
</view>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</view>
</uni-popup>
</view>
</template>
<script type="text/babel">
2021-11-07 23:51:59 +08:00
import uniPopup from './uni-popup/uni-popup.vue'
import uniPopupMessage from './uni-popup/uni-popup-message.vue'
import uniPopupDialog from './uni-popup/uni-popup-dialog.vue'
2020-07-12 22:44:37 +08:00
export default {
2021-11-07 23:51:59 +08:00
name: 'CitySelect',
2020-07-12 22:44:37 +08:00
components: {
uniPopup,
uniPopupMessage,
2021-11-07 23:51:59 +08:00
uniPopupDialog,
2020-07-12 22:44:37 +08:00
},
2021-11-07 23:51:59 +08:00
props: ['callback', 'items', 'defaultValue'],
2020-07-12 22:44:37 +08:00
data() {
return {
2021-11-07 23:51:59 +08:00
value: '请选择',
2020-07-12 22:44:37 +08:00
show: this.value,
province: [],
provinceActive: null,
city: [],
cityActive: null,
district: [],
districtActive: null,
2021-11-07 23:51:59 +08:00
current: 0,
}
2020-07-12 22:44:37 +08:00
},
watch: {
2021-11-07 23:51:59 +08:00
items(next) {
this.province = next
},
defaultValue(next) {
this.value = `${next.province.n} ${next.city.n} ${next.district.n}`
this.setDefaultValue(this.items, next)
},
2020-07-12 22:44:37 +08:00
},
2021-11-07 23:51:59 +08:00
2020-07-12 22:44:37 +08:00
mounted() {
2021-11-07 23:51:59 +08:00
console.log(this)
if (this.value) {
2021-11-07 23:51:59 +08:00
this.value = this.value
2020-07-12 22:44:37 +08:00
}
2021-11-07 23:51:59 +08:00
this.province = this.items
2020-07-12 22:44:37 +08:00
},
methods: {
2021-11-07 23:51:59 +08:00
isProvinceActive(item) {
return this.provinceActive && item.v == this.provinceActive.v
},
isCityActive(item) {
return this.cityActive && item.v == this.cityActive.v
},
isDistrictActive(item) {
return this.districtActive && item.v == this.districtActive.v
},
setDefaultValue(items, value) {
if (!items || !value) {
return
}
this.province = items
items.map(province => {
if (province.n == value.province.n) {
this.city = province.c
this.provinceActive = {
v: province.v,
n: value.province.n,
}
province.c.map(city => {
if (city.n == value.city.n) {
this.district = city.c
this.cityActive = {
v: city.v,
n: value.city.n,
}
city.c.map(district => {
if (district.n == value.district.n) {
this.districtActive = {
v: city.v,
n: value.district.n,
}
}
})
}
})
}
})
console.log(this.provinceActive, this.cityActive, this.districtActive)
console.log(this)
},
2020-07-12 22:44:37 +08:00
open() {
2021-11-07 23:51:59 +08:00
this.province = this.items
this.provinceActive = null
this.cityActive = null
this.districtActive = null
this.city = []
this.district = []
this.current = 0
this.$refs.popup.open()
this.setDefaultValue(this.items, this.defaultValue)
2020-07-12 22:44:37 +08:00
},
changeNav(index) {
if (index == 0) {
2021-11-07 23:51:59 +08:00
this.provinceActive = null
2020-07-12 22:44:37 +08:00
}
if (index == 1) {
2021-11-07 23:51:59 +08:00
this.cityActive = null
2021-11-07 23:55:15 +08:00
this.districtActive = null
2020-07-12 22:44:37 +08:00
}
if (index == 2) {
2021-11-07 23:51:59 +08:00
this.districtActive = null
2020-07-12 22:44:37 +08:00
}
2021-11-07 23:51:59 +08:00
this.current = index
2020-07-12 22:44:37 +08:00
},
selectProvince(index) {
2021-11-07 23:51:59 +08:00
this.provinceActive = this.province[index]
this.city = this.province[index].c
this.current = 1
2020-07-12 22:44:37 +08:00
},
selectCity(index) {
2021-11-07 23:51:59 +08:00
this.cityActive = this.city[index]
this.district = this.city[index].c
this.current = 2
2020-07-12 22:44:37 +08:00
},
selectDistrict(index) {
2021-11-07 23:51:59 +08:00
this.districtActive = this.district[index]
this.value = `${this.provinceActive.n} ${this.cityActive.n} ${this.districtActive.n}`
2020-07-12 22:44:37 +08:00
// this.callback({
// province: {
// id: this.provinceActive.v,
// name: this.provinceActive.n
// },
// city: {
// id: this.cityActive.v,
// name: this.cityActive.n
// },
// district: {
// id: this.districtActive.v,
// name: this.districtActive.n
// }
// });
2021-11-07 23:51:59 +08:00
this.$emit('callback', {
2020-07-12 22:44:37 +08:00
province: {
id: this.provinceActive.v,
2021-11-07 23:51:59 +08:00
name: this.provinceActive.n,
2020-07-12 22:44:37 +08:00
},
city: {
id: this.cityActive.v,
2021-11-07 23:51:59 +08:00
name: this.cityActive.n,
2020-07-12 22:44:37 +08:00
},
district: {
id: this.districtActive.v,
2021-11-07 23:51:59 +08:00
name: this.districtActive.n,
},
})
this.$refs.popup.close()
},
},
}
2020-07-12 22:44:37 +08:00
</script>
<style lang="less">
.cityselect {
width: 100%;
height: 75%;
background-color: #fff;
z-index: 1502;
position: relative;
2021-11-07 23:51:59 +08:00
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
2020-07-12 22:44:37 +08:00
.cityScroll {
height: 100%;
}
.swiper {
2021-11-07 23:51:59 +08:00
height: 800rpx;
2020-07-12 22:44:37 +08:00
}
}
.cityselect-header {
width: 100%;
z-index: 1;
}
.cityselect-title {
width: 100%;
font-size: 30rpx;
text-align: center;
height: 95rpx;
line-height: 95rpx;
position: relative;
&:cityselect-title:after {
height: 1px;
position: absolute;
z-index: 0;
bottom: 0;
left: 0;
2021-11-07 23:51:59 +08:00
content: '';
2020-07-12 22:44:37 +08:00
width: 100%;
background-image: linear-gradient(0deg, #ececec 50%, transparent 0);
}
}
.cityselect-nav {
width: 100%;
padding-left: 20rpx;
overflow: hidden;
display: flex;
align-items: center;
justify-content: flex-start;
.item {
font-size: 26rpx;
color: #222;
display: block;
height: 80rpx;
line-height: 92rpx;
padding: 0 16rpx;
position: relative;
margin-right: 30rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 40%;
&.active {
color: #f23030 !important;
border-bottom: 1rpx solid #f23030;
}
}
}
.cityselect-content {
height: 100%;
width: 100%;
}
.cityselect-item {
.cityselect-item-box {
display: block;
padding: 0 40rpx;
position: relative;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-all;
text-overflow: ellipsis;
line-height: 64rpx;
max-height: 65rpx;
font-size: 26rpx;
color: #333;
2021-11-07 23:51:59 +08:00
&.active{
color:#f23030 !important;
}
2020-07-12 22:44:37 +08:00
&:after {
2021-11-07 23:51:59 +08:00
content: '';
2020-07-12 22:44:37 +08:00
height: 1rpx;
position: absolute;
z-index: 0;
bottom: 0;
left: 0;
width: 100%;
background-image: linear-gradient(0deg, #ececec 50%, transparent 0);
}
}
}
</style>