背景:最近项目中原来多城市选择下拉组件老板嫌找城市麻烦,并且很多区域没有项目。所以新增一个搜索的页面。页面返回多省市区为自己后段返回多有项目的省市。所以自己做了一个切换tab并且可小程序内城市搜索的页面
<template>
<view class="column-flex-container page-city-select">
<NavBar
back-text=""
>
<text class="cuIcon-search" />
<input
v-model="searchValue"
class="search-input"
placeholder="请输入城市或省份"
type="text"
:focus="true"
confirmType="search"
@input="onInput"
@blur="onBlur"
@confirm="onConfirm"
>
<text v-show="searchValue.length" @tap="clear" class="cuIcon cuIcon-roundclosefill clear" />
</NavBar>
<view v-if="searchValue.length === 0" class="city-nav">
<view @tap="cityChange(0)" class="city-nav-item" :class="cityIndex===0 ? 'active' : ''">按区域</view>
<view @tap="cityChange(1)" class="city-nav-item" :class="cityIndex===1 ? 'active' : ''">按城市</view>
</view>
<view
v-if="searchValue.length === 0"
class="layout-container city-body"
>
<view
v-for="(item, index) in (cityIndex ? cityList : provinceList)"
:key="index"
class="city-list"
@tap="areaSelect(item)"
>
<view :class="item.place === optinosCity ? 'selected': ''">
{{ item.place }}
<text v-if="item.place === optinosCity" @tap="clear" class="cuIcon cuIcon-check" />
</view>
</view>
</view>
<view
v-else
class="layout-container city-body"
>
<view
v-for="(item, index) in provinceAndCityList.filter(item => item.place.indexOf(searchValue) !== -1)"
:key="index"
class="city-list"
@tap="areaSelect(item)"
>
<view :class="item.place === optinosCity ? 'selected': ''">
{{ item.place }}
<text v-if="item.place === optinosCity" class="cuIcon cuIcon-check" />
</view>
</view>
</view>
</view>
</template>
<script>
import { getAllProvinceAndCities } from '@/api/metadata'
import { mapGetters, mapMutations } from 'vuex'
export default {
name: 'PageCitySelect',
data () {
return {
provinceList: [],
cityList: [],
provinceAndCityList: [],
cityIndex: 0,
searchValue: '',
optinosCity: '全国'
}
},
created() {
this.getProvinceAndCity()
},
onLoad(options) {
// console.log(decodeURI(options.area));
// if (options.area) {
// this.optinosCity = options.area
// }
},
computed: {
...mapGetters('areaSelect', ['place']),
},
methods: {
...mapMutations('areaSelect', ['setPlace']),
getProvinceAndCity() {
if (this.place.place) {
this.optinosCity = this.place.place
}
getAllProvinceAndCities().then((data) => {
console.log(data);
this.cityList = data.data.cities.map(item => {
return {
...item,
type: 2
}
})
this.provinceList = data.data.provinces.map(item => {
return {
...item,
type: 1
}
})
this.provinceAndCityList = [...this.cityList, ...this.provinceList]
})
},
cityChange(i){
this.cityIndex = i
},
onInput () {
console.log(this.searchValue);
},
onBlur () {
this.searchValue = this.searchValue.trim()
},
areaSelect (val) {
this.setPlace(val)
this.$navigateTo(1)
},
onConfirm () {
this._getDateList()
},
clear() {
this.searchValue = ''
}
}
}
</script>
<style lang="scss">
.page-city-select{
.search-input {
width: 220px;
height: 28px;
line-height: 28px;
color: #323232;
background: #F5F5F5;
border-radius: 14px;
text-align: left;
box-sizing: border-box;
padding-left: 30px;
font-weight: 400;
padding-right: 30px;
}
.cu-custom .cu-bar .content {
width: calc(100% - 180rpx)!important;
font-weight: 600;
}
.cuIcon-search:before {
content: "";
width: 10.5px;
height: 10.5px;
position: absolute;
font-size: 10.5px;
left: 12px;
color: rgba(111, 111, 111, 1);
}
.city-nav {
display: flex;
background: #fff;
border-bottom: 1rpx solid #F5F5F5;
padding: 16px 0 16px 0;
color: #999999;
&-item {
width: 50%;
text-align: center;
position: relative;
}
}
.city-body {
background: #fff;
padding-bottom: 60px;
.city-list {
padding: 13px 18px;
color: #323232;
font-size: 16px;
position: relative;
}
}
.active {
color: #323232;
font-weight: 600;
}
.active::after {
content: '';
width: 18px;
height: 3px;
background: #E64A4A;
border-radius: 3px;
position: absolute;
bottom: -6px;
left: 50%;
transform: translateX(-50%);
}
.clear {
color: #C6C6C6;
position: absolute;
top: -1px;
right: 24%;
padding-right: 6px;
z-index: 11;
}
.selected {
color: #E64A4A;
}
.cuIcon-check{
position: absolute;
right: 18px;
font-weight: 400;
font-size: 16.5px;
// font-size: 14px;
}
}
</style>