This commit is contained in:
shuhongfan
2023-09-04 16:40:17 +08:00
commit cf5ac25c14
8267 changed files with 1305066 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
.selectArea{
::v-deep .uni-popup__wrapper {
height: 1160rpx;
background-color: white !important;
border-radius: 24rpx 24rpx 0 0;
}
.header {
display: flex;
height: 56rpx;
padding: 30rpx 38rpx;
align-items: center;
justify-content: space-between;
border-radius: 24rpx 24rpx 0 0;
.header-title {
font-size: 32rpx;
color: #151515;
font-weight: bold;
}
.close {
width: 24rpx;
height: 24rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/icon21.png');
}
}
.seachBox{
::v-deep .uni-searchbar{
padding-left: 38rpx!important;
.uni-searchbar__box{
border-radius: 34rpx!important;
}
}
.search-icon{
width: 40rpx;
height: 40rpx;
background-repeat: no-repeat;
background-size: contain;
background-image: url('../../../static/search.png');
}
}
.hot-city{
margin-top: 31rpx;
border-bottom: 2rpx solid #F4F4F4;
padding-bottom: 40rpx;
margin: 0 38rpx;
.title{
font-size: 24rpx;
color: #888;
}
.city-box{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.city-item{
font-size: 24rpx;
height: 64rpx;
background: #F4F4F4;
border-radius: 34rpx;
min-width: 148rpx;
margin-top: 18rpx;
text-align: center;
line-height: 64rpx;
}
.city-item.active{
border: 2rpx solid #E84134;
color: #E84134;
background-color: white;
}
}
}
.province-city-area{
margin-top: -10rpx;
.picker-view {
width: 750rpx;
height: 600rpx;
margin-top: 20rpx;
}
.item {
height: 50px;
align-items: center;
justify-content: center;
text-align: center;
display: flex;
}
::v-deep .uni-picker-view-wrapper{
.uni-picker-view-mask{
display: none;
}
.uni-picker-view-indicator{
top: 46%!important;
}
}
.label-box{
display: flex;
align-items: center;
justify-content: space-between;
padding: 40rpx 90rpx;
.label{
font-size: 30rpx;
font-weight: bold;
}
}
}
.footer{
height: 168rpx;
width: 100%;
background-color: white;
position: fixed;
bottom: 0;
left: 0;
padding-top: 80rpx;
display: flex;
align-items: center;
.btn{
width: 404rpx;
height: 88rpx;
background: #E84134;
border-radius: 44rpx;
color:white ;
text-align: center;
line-height: 88rpx;
font-size: 30rpx;
margin: 0 auto;
}
}
}

View File

@@ -0,0 +1,258 @@
<template>
<view class="selectArea">
<uni-popup ref="popup" type="bottom">
<view class="header">
<view class="header-title">选择省市区</view>
<view class="close" @click="handleCancel"></view>
</view>
<!-- 搜索框 -->
<!-- <view class="seachBox">
<uni-search-bar placeholder="请输入城市/区县/街道名称搜索" cancelButton="none" @confirm="search" :focus="true"
v-model="searchValue" @blur="blur" @focus="focus" @input="input">
<template v-slot:searchIcon>
<view class="search-icon"></view>
</template>
</uni-search-bar>
</view> -->
<!-- 热门城市 -->
<view class="hot-city">
<view class="title">热门城市</view>
<view class="city-box">
<view class="city-item" :class="index===hotCityIndex?'active':''" v-for="(item,index) in cityList" :key="index"
@click="handleHotCityClick(item,index)">
{{item.label}}
</view>
</view>
</view>
<!-- 省市区三级联动 -->
<view class="province-city-area">
<view class="label-box">
<view class="label">省份</view>
<view class="label">城市</view>
<view class="label">区县</view>
</view>
<picker-view :value="areaIndex.data" :indicator-style="`height: 50px;`" @change="bindChange"
@pickstart="handlePickStart" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item,index) in province.data" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in city.data" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in area.data" :key="index">{{item.name}}</view>
</picker-view-column>
</picker-view>
</view>
<!-- 底部 -->
<view class="footer">
<view class="btn" @click="confirm">确定</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted,
nextTick,
computed,
watch
} from 'vue';
import {
getArea
} from '@/pages/api/order.js'
import {
onLoad,
onShow
} from '@dcloudio/uni-app';
const emits = defineEmits(["@getAreaData"]);
const popup = ref()
let props = defineProps({
provinceId: {
type: String,
default: '',
},
cityId: {
type: String,
default: '',
},
countyId: {
type: String,
default: '',
}
})
//省数据
let province = reactive({
data: []
})
let selectedProvince = reactive({
data: {
name: '北京市',
id: '1'
}
})
//市数据
const city = reactive({
data: []
})
let selectedCity = reactive({
data: {
name: '直辖市',
id: '2'
}
})
//区域数据
const area = reactive({
data: []
})
let selectedArea = reactive({
data: {
name: '东城区',
id: '3'
}
})
//记录三级联动每项的index以及默认展示
let areaIndex = reactive({
data: [0, 0, 0]
})
//记录热门城市选中的索引
let hotCityIndex = ref('')
const cityList = reactive([{
label: '北京',
provinceId: "1",
cityId: "2",
countyId: "3"
},
{
label: '上海',
provinceId: "161792",
cityId: "161793",
countyId: "161794"
},
{
label: '广州',
provinceId: "483250",
cityId: "483251",
countyId: "483252"
},
{
label: '深圳',
provinceId: "483250",
cityId: "487721",
countyId: "487722"
}
])
//负责记录组件中选中的三级对应的id
let placeIdItem = reactive({
provinceId: '',
cityId: '',
countyId: ''
})
//区分热门城市点击还是滑动三级组件
let chooseType = ref('select')
// 监听后台获取的详情
watch(props, (newValue, oldValue) => {
placeIdItem.provinceId = newValue.provinceId
placeIdItem.cityId = newValue.cityId
placeIdItem.countyId = newValue.countyId
})
const handleHotCityClick = (item,index) => {
placeIdItem.provinceId = item.provinceId
placeIdItem.cityId = item.cityId
placeIdItem.countyId = item.countyId
getAreaInfo('', province)
getAreaInfo(placeIdItem.provinceId, city)
getAreaInfo(placeIdItem.cityId, area)
chooseType.value = 'click'
hotCityIndex.value = index
}
const getList = () => {
getAreaInfo('', province)
getAreaInfo(placeIdItem.provinceId || 1, city)
getAreaInfo(placeIdItem.cityId || 2, area)
}
//获取省市区
const getAreaInfo = (parentId, type) => {
getArea({
parentId
}).then((res) => {
type.data = res.data
if (type === province) {
//用于解决响应式状态变更但是dom不更新的问题
nextTick(() => {
selectedProvince.data = res.data.filter(item => item.id == placeIdItem.provinceId)[0]|| res.data[0]
areaIndex.data[0] = res.data.findIndex(item => item.id == placeIdItem.provinceId)
})
} else if (type === city) {
nextTick(() => {
selectedCity.data = res.data.filter(item => item.id == placeIdItem.cityId)[0]|| res.data[0]
areaIndex.data[1] = res.data.findIndex(item => item.id == placeIdItem.cityId)
})
} else if (type === area) {
nextTick(() => {
selectedArea.data = res.data.filter(item => item.id == placeIdItem.countyId)[0]|| res.data[0]
areaIndex.data[2] = res.data.findIndex(item => item.id == placeIdItem.countyId)
})
}
})
}
const handlePickStart = () => {
chooseType.value = 'select'
}
//选择省市区
const bindChange = (event) => {
if(chooseType.value ==='click') return
//二级地址获取
if (areaIndex.data[0] !== event.detail.value[0]) {
getAreaInfo(province.data[event.detail.value[0]].id, city)
getAreaInfo(Number(province.data[event.detail.value[0]].id) + 1, area)
selectedProvince.data = province.data[event.detail.value[0]]
} else if (areaIndex.data[1] !== event.detail.value[1]) {
//三级地址获取
getAreaInfo(city.data[event.detail.value[1]].id, area)
selectedCity.data = city.data[event.detail.value[1]]
} else {
selectedArea.data = area.data[event.detail.value[2]]
}
areaIndex.data = event.detail.value
hotCityIndex.value = ''
}
// 打开弹层
const handleOpen = () => {
popup.value.open('bottom');
};
// 关闭弹层
const handleCancel = () => {
popup.value.close('bottom');
}
//确认选择省市区
const confirm = () => {
handleCancel()
emits("getAreaData", {
province: selectedProvince.data,
city: selectedCity.data,
area: selectedArea.data
})
}
// 暴漏给父组件
defineExpose({
handleOpen,
getList
});
</script>
<style src="./selectArea.scss" lang="scss" scoped></style>