1.组件代码
<template>
<!-- 地址筛选 -->
<u-popup :show="visible" @close="closeVisible" @open="openVisible" round="10" closeable bgColor="#F8F8F8">
<view class="city-popup">
<view class="title">
推荐地址
</view>
<view class="recommen-city">
<span v-for="(item,index) in recommen" :key="index"
:class="{'active-city':city.includes(item)}" @click="handleCity(item)">{{item}}</span>
</view>
<view class="letter-city">
<view class="left-letter">
<a v-for="(item,index) in letterList" :key="index"
:class="currentViewId==`section-${item}`?'letter-item active-letter':'letter-item'"
@click="scrollToSection(item)">{{item}}</a>
</view>
<scroll-view class="right-city" scroll-y :scroll-into-view="currentViewId" scroll-with-animation
:scroll-top="scrollTop">
<view v-for="(e, index) in cityList" :key="index" :id="'section-'+e.letter">
<view class="province-group">
<view class="group-title">{{ e.province }}:</view>
<view class="city-list">
<view v-for="(i, k) in e.children" :key="k" :class="city.includes(i.name)?'city-item active-item':'city-item'"
@click="selectProvince(i)">
{{ i.name }}
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</u-popup>
</template>
<script>
export default {
name: "city-select",
props: {
visible: {
type: Boolean,
default: true
},
city: {
type: String,
default: ''
},
cityList: {
type: Array,
default: () => []
},
letterList: {
type: Array,
default: () => []
},
},
data() {
return {
currentViewId: '',
recommen: ['西安', '北京', '重庆', '洛阳', '大理', '汉中', '榆林', '洛阳', '大理', '汉中', '榆林'],
};
},
onShow() {
},
watch: {
},
methods: {
openVisible() {
this.$emit('openCity', true)
},
closeVisible() {
this.$emit('closeCity', false)
},
scrollToSection(letter) {
this.currentViewId = 'section-' + letter;
},
selectProvince(city) {
this.$emit('changeCity', city.name)
this.closeVisible()
},
handleCity(city) {
let str = ''
if(!city.includes('市')){
str = city + '市'
}else{
str = city
}
this.$emit('changeCity', str)
this.closeVisible()
}
}
}
</script>
<style lang="scss">
.city-popup {
.title {
height: 7vh;
line-height: 7vh;
font-weight: bold;
font-size: 31rpx;
color: #000000;
border-bottom: 2rpx solid #E4E4E4;
background-color: #fff;
padding: 0 26rpx;
box-sizing: border-box;
}
.recommen-city {
background-color: #fff;
padding: 26rpx;
box-sizing: border-box;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
margin-bottom: 10rpx;
span {
line-height: 50rpx;
font-weight: 500;
font-size: 25rpx;
color: #999999;
text-align: center;
background: #F3F5F9;
border-radius: 9rpx;
}
.active-city {
background: #D7FAF6 !important;
color: #009F9A !important;
}
}
.letter-city {
height: 60vh;
display: flex;
.left-letter {
width: 130rpx;
height: 100%;
overflow: auto;
padding: 26rpx 0;
box-sizing: border-box;
background-color: #fff;
margin-right: 10rpx;
.letter-item{
font-weight: 500;
font-size: 31rpx;
color: #666666;
line-height: 56rpx;
border-radius: 9rpx;
margin-bottom: 40rpx;
text-align: center;
}
.active-letter{
background: linear-gradient( 90deg, #4BFFAB 0%, #00A37C 100%) !important;
color: #fff !important;
}
}
.right-city {
flex: 1;
overflow: auto;
padding: 26rpx;
box-sizing: border-box;
background-color: #fff;
.province-group {
margin-bottom: 30rpx;
.group-title {
font-weight: 500;
font-size: 29rpx;
color: #333333;
margin-bottom: 20rpx;
}
.city-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
.city-item {
line-height: 50rpx;
font-weight: 500;
font-size: 24rpx;
color: #999999;
text-align: center;
background: #F3F5F9;
border-radius: 9rpx;
}
.active-item {
background: #D7FAF6 !important;
color: #009F9A !important;
}
}
}
}
}
}
</style>
2.父组件引用
import citySelect from '@/components/city-select/city-select.vue';
//组件注册
components: {
citySelect
},
3.父组件所需data
city: uni.getStorageSync('userCity')?uni.getStorageSync('userCity'):'北京',
isAddressShow: false,
cityList: [],
letterList:[],
//上面数组内容模拟数据如下 具体可根据个人接口重新整理
cityList:[
{
children: [,…]
0: {id: 340800, parent_id: 340000, name: "安庆市", province: "安徽省", city: "安庆市", letter: "A", children: []}
1: {id: 340300, parent_id: 340000, name: "蚌埠市", province: "安徽省", city: "蚌埠市", letter: "B", children: []}
2: {id: 341600, parent_id: 340000, name: "亳州市", province: "安徽省", city: "亳州市", letter: "B", children: []}
3: {id: 341100, parent_id: 340000, name: "滁州市", province: "安徽省", city: "滁州市", letter: "C", children: []}
4: {id: 341700, parent_id: 340000, name: "池州市", province: "安徽省", city: "池州市", letter: "C", children: []}
5: {id: 341200, parent_id: 340000, name: "阜阳市", province: "安徽省", city: "阜阳市", letter: "F", children: []}
6: {id: 340100, parent_id: 340000, name: "合肥市", province: "安徽省", city: "合肥市", letter: "H", children: []}
7: {id: 340400, parent_id: 340000, name: "淮南市", province: "安徽省", city: "淮南市", letter: "H", children: []}
8: {id: 340600, parent_id: 340000, name: "淮北市", province: "安徽省", city: "淮北市", letter: "H", children: []}
9: {id: 341000, parent_id: 340000, name: "黄山市", province: "安徽省", city: "黄山市", letter: "H", children: []}
10: {id: 341500, parent_id: 340000, name: "六安市", province: "安徽省", city: "六安市", letter: "L", children: []}
11: {id: 340500, parent_id: 340000, name: "马鞍山市", province: "安徽省", city: "马鞍山市", letter: "M", children: []}
12: {id: 341300, parent_id: 340000, name: "宿州市", province: "安徽省", city: "宿州市", letter: "S", children: []}
13: {id: 340700, parent_id: 340000, name: "铜陵市", province: "安徽省", city: "铜陵市", letter: "T", children: []}
14: {id: 340200, parent_id: 340000, name: "芜湖市", province: "安徽省", city: "芜湖市", letter: "W", children: []}
15: {id: 341800, parent_id: 340000, name: "宣城市", province: "安徽省", city: "宣城市", letter: "X", children: []}
city: ""
id: 340000
letter: "A"
name: "安徽省"
parent_id: 100000
province: "安徽省"
}
]
4.父组件定义函数传递子组件
//接口获取省市数据
getCity() {
this.$http.get('你自己的接口url', {}, {
custom: {
loading: false,
auth: false
}
}).then(res => {
console.log('城市信息', res);
if (res.code == 0) {
let arr = res.data.map(e=>{
return e.letter
})
this.letterList = [...new Set(arr)]
this.cityList = res.data
}
})
},
openCity(val) {
this.isAddressShow = val
},
closeCity(val) {
this.isAddressShow = val
},
changeCity(val){
uni.setStorageSync('userCity',val)
this.city = val
},