// 鑒于市面上沒有好用的移動(dòng)端多選級(jí)聯(lián)選擇器,自己手寫了一個(gè)
// 地區(qū)選擇器
<template>
<view class="addressSelector">
<main>
<view class="provinceTree">
<view @click="getCityList(item, index)" :id="item.code" :class="item.checked === false ? 'provinceBox' : 'provinceBox provinceHeightLight'" v-for="(item, index) in provinceList" :key="item.code">
<span>{{item.name}}</span>
<i v-if="item.number !== ''">{{item.number}}</i>
</view>
</view>
<view class="cityTree">
<view @click="getAreaList(item, index)" :id="item.code" :class="item.checked === false ? 'cityBox' : 'cityBox cityHeightLight'" v-for="(item, index) in cityList" :key="item.code">
<span>{{item.name}}</span>
<i v-if="item.number !== ''">{{item.number}}</i>
</view>
</view>
<view class="areaTree">
<view @click="clickAreaList(item, index)" :id="item.code" :class="item.checked === false ? 'areaBox' : 'areaBox areaHeightLight'" v-for="(item, index) in areaList" :key="item.code">{{item.name}}</view>
</view>
</main>
<u-top-tips z-index="99999" ref="uTips"></u-top-tips>
</view>
</template>
<script>
import { addressPartListApi } from '../../../api/api'
export default {
data() {
return {
// 省級(jí)城市編碼
pcode: '',
// 市級(jí)城市編碼
ccode: '110000',
// 省份列表
provinceList: [],
// 市級(jí)列表
cityList: [],
// 區(qū)縣列表
areaList: [],
// 存儲(chǔ)選中的省份列表
checkedProvinceList: [],
// 存儲(chǔ)選中的市級(jí)列表
checkedCityList: [],
// 存儲(chǔ)選中的區(qū)縣級(jí)列表
checkedAreaList: []
}
},
onShow() {
// 獲取省份列表
this.getProvinceList().then(() => {
// 獲取默認(rèn)市級(jí)列表
this.getCityList({ code:'110000', pcode: '000000' }, 0)
})
},
methods: {
// 獲取省份列表
async getProvinceList() {
const { data: res } = await addressPartListApi('000000')
if (res.code !== 0) return this.refs.uTips.show({ title: res.msg, type: 'error', duration: '2000'})
// 設(shè)置默認(rèn)值
this.cityList = []
res.data.list.forEach((item, index) => {
this.cityList.push({
id: item.id, // 地區(qū)id
name: item.name, // 地區(qū)名稱
code: item.code, // 地區(qū)編碼
pcode: item.pcode, // 父級(jí)地區(qū)編碼
checked: false, // 選擇狀態(tài)
switch: false, // 切換狀態(tài)
number: '', // 子級(jí)選中的值
index: index // 當(dāng)前地區(qū)的下標(biāo)
})
})
// 2.市級(jí)高亮
this.checkedCityList.forEach((checkCity, checkIndex) => {
this.cityList.forEach((allCity, allIndex) => {
if (checkCity.code === allCity.code) {
this.cityList[allIndex].checked = true
this.cityList[allIndex].number = this.checkedCityList[checkIndex].number
}
})
})
// 3.直接將所有區(qū)縣級(jí)列表清空
this.areaList = []
// 4.將所有省份switch改為false,同時(shí)將當(dāng)前選中的省份switch改為true
this.provinceList.forEach(zResult => {
zResult.switch = false
})
this.provinceList[index].switch = true
return false
// 如果當(dāng)前省級(jí)已經(jīng)被點(diǎn)擊過,但是不是第一次點(diǎn)擊時(shí)
} else if (alreadyCheck === true && value.switch === true) {
// 除了移除省級(jí)code還要移除對(duì)應(yīng)省級(jí)下的所有市級(jí)code(移除對(duì)應(yīng)的高亮狀態(tài),默認(rèn)會(huì)重置)
// 將省級(jí)code和市級(jí)級(jí)pcode比較如果相同則移除(第一層)
if (this.checkedCityList.length !== 0) {
// --------------移除對(duì)應(yīng)的市級(jí)code
let newCheckedCityList = []
this.checkedCityList.forEach((val, index) => {
if (value.code !== val.pcode) {
newCheckedCityList.push(val)
} else {
// 將對(duì)應(yīng)的市級(jí)code和區(qū)縣級(jí)pcode比較如果相同則移除(第二層)
if (this.checkedAreaList.length !== 0) {
let newCheckedAreaList = []
this.checkedAreaList.forEach((keys, index) => {
if (val.code !== keys.pcode) {
newCheckedAreaList.push(keys)
}
})
this.checkedAreaList = newCheckedAreaList
}
}
})
this.checkedCityList = newCheckedCityList
}
this.checkedProvinceList.splice(alreadyIndex, 1)
} else {
this.checkedProvinceList.push({ code: value.code, pcode: value.pcode, number: '全' })
}
console.log(this.checkedProvinceList, '省', this.checkedCityList, '市', this.checkedAreaList,'區(qū)縣')
// 改變當(dāng)前點(diǎn)擊的省份高亮狀態(tài)
this.provinceList[index].checked = !this.provinceList[index].checked
// 改變當(dāng)前點(diǎn)擊省份的全選狀態(tài)
if (this.provinceList[index].number === '') {
this.provinceList[index].number = '全'
} else {
this.provinceList[index].number = ''
}
this.pcode = value.code
const { data: res } = await addressPartListApi(this.pcode)
if (res.code !== 0) return this.refs.uTips.show({ title: res.msg, type: 'error', duration: '2000'})
// 設(shè)置默認(rèn)值
this.areaList = []
res.data.list.forEach((item, index) => {
this.areaList.push({
id: item.id, // 地區(qū)id
name: item.name, // 地區(qū)名稱
code: item.code, // 地區(qū)編碼
pcode: item.pcode, // 父級(jí)地區(qū)編碼
checked: false, // 選擇狀態(tài)
switch: false, // 切換狀態(tài)
number: '', // 子級(jí)選中的值
index: index // 當(dāng)前地區(qū)的下標(biāo)
})
})
// 2.區(qū)縣高亮
this.checkedAreaList.forEach((checkArea, checkIndex) => {
this.areaList.forEach((allArea, allIndex) => {
if (checkArea.code === allArea.code) {
this.areaList[allIndex].checked = true
}
})
})
// 3.將所有市級(jí)switch改為false,同時(shí)將當(dāng)前選中的市級(jí)switch改為true
this.cityList.forEach(zResult => {
zResult.switch = false
})
this.cityList[index].switch = true
return false
// 如果當(dāng)前市級(jí)已經(jīng)被點(diǎn)擊過,但是不是第一次點(diǎn)擊時(shí)
} else if (alreadyCheck === true && value.switch === true) {
this.checkedCityList.splice(alreadyIndex, 1)
// 除了移除市級(jí)code還要移除對(duì)應(yīng)市級(jí)下的所有區(qū)縣級(jí)code同時(shí)移除對(duì)應(yīng)的高亮狀態(tài)
// 將市級(jí)code和區(qū)縣級(jí)pcode比較如果相同則移除
if (this.checkedAreaList.length !== 0) {
let newCheckedAreaList = []
this.checkedAreaList.forEach((val, index) => {
if (value.code !== val.pcode) {
newCheckedAreaList.push(val)
}
})
this.checkedAreaList = newCheckedAreaList
}
// 當(dāng)市級(jí)已經(jīng)被勾選時(shí),找到對(duì)應(yīng)的省級(jí),省級(jí)后綴的數(shù)字得-1
this.provinceList.forEach((result, index) => {
if (result.code === value.pcode) {
result.number = (result.number - 1) + ''
}
if (result.number === '0') result.number = '全'
// 不僅要改list的number還要改對(duì)應(yīng)的checkedList上的number★~~~~~
if (this.checkedProvinceList.length !== 0) {
this.checkedProvinceList.forEach((redus, rIndex) => {
if (redus.code === result.code) {
this.checkedProvinceList[rIndex].number = result.number
}
})
}
})
} else {
this.checkedCityList.push({ code: value.code, pcode: value.pcode, number: '全' })
// 勾選時(shí)點(diǎn)擊當(dāng)前市級(jí)地區(qū)時(shí)判斷當(dāng)前省級(jí)是否勾選,如果未勾選則勾選上(checked選擇狀態(tài)及高亮)
// 判斷當(dāng)前省級(jí)是否勾選
this.provinceList.forEach((result, index) => {
// 找到對(duì)應(yīng)的省級(jí)
if (result.code === value.pcode) {
// 如果省級(jí)未勾選,則勾選上省級(jí)
if (result.checked === false) {
result.checked = true
result.number = '全'
this.checkedProvinceList.push({ code: value.pcode, pcode: '000000', number: '1' })
}
// 到這一步肯定省級(jí)肯定是被勾選上了
// 如果市級(jí)被勾選,省級(jí)后綴的數(shù)字都得+1
if (result.number === '全') {
result.number = '1'
} else {
result.number = (result.number - 0 + 1) + ''
}
// 不僅要改list的number還要改對(duì)應(yīng)的checkedList上的number★~~~~~
if (this.checkedProvinceList.length !== 0) {
this.checkedProvinceList.forEach((redus, rIndex) => {
if (redus.code === result.code) {
this.checkedProvinceList[rIndex].number = result.number
}
})
}
}
})
}
// 改變當(dāng)前點(diǎn)擊的市級(jí)高亮狀態(tài)
this.cityList[index].checked = !this.cityList[index].checked
// 改變當(dāng)前點(diǎn)擊市級(jí)的全選狀態(tài)
if (this.cityList[index].number === '') {
this.cityList[index].number = '全'
} else {
this.cityList[index].number = ''
}
this.ccode = value.code
console.log(this.checkedProvinceList, '省', this.checkedCityList, '市', this.checkedAreaList,'區(qū)縣')
const { data: res } = await addressPartListApi(this.ccode)
if (res.code !== 0) return this.$refs.uTips.show({ title: res.msg, type: 'error', duration: '2000'})
// 設(shè)置默認(rèn)值
this.areaList = []
res.data.list.forEach((item, index) => {
this.areaList.push({
id: item.id, // 地區(qū)id
name: item.name, // 地區(qū)名稱
code: item.code, // 地區(qū)編碼
pcode: item.pcode, // 父級(jí)地區(qū)編碼
checked: false, // 選擇狀態(tài)
switch: false,// 切換狀態(tài)
index: index // 當(dāng)前地區(qū)的下標(biāo)
})
})
// ------------------------------------------------------------------------------------------------(再獲取完區(qū)縣級(jí)列表后點(diǎn)擊市級(jí)重置區(qū)縣級(jí)高亮)
// 用所有被勾選的區(qū)縣級(jí)code和所有區(qū)縣列表進(jìn)行比較如果相同則高亮
if (this.checkedAreaList.length !== 0 && this.areaList.length !== 0) {
this.checkedAreaList.forEach((val, valIndex) => {
this.areaList.forEach((keys, keysIndex)=> {
if (val.code === keys.code) {
this.areaList[keysIndex].checked = true
}
})
})
}
},
// 點(diǎn)擊區(qū)縣觸發(fā)
clickAreaList(value, index) {
// 存儲(chǔ)被點(diǎn)擊的區(qū)縣code(判斷如果已經(jīng)存在被點(diǎn)擊過則去除)
let alreadyCheck = false
let alreadyIndex = ''
if (this.checkedAreaList.length !== 0) {
this.checkedAreaList.forEach((item, index) => {
if (item.code === value.code) {
alreadyCheck = true
alreadyIndex = index
return false
}
})
}
// 如果當(dāng)前縣區(qū)級(jí)已經(jīng)被勾選則去除
if (alreadyCheck === true) {
this.checkedAreaList.splice(alreadyIndex, 1)
// 去除的時(shí)候市級(jí)肯定是勾選狀態(tài)
this.cityList.forEach((result, index) => {
// 找到對(duì)應(yīng)的市級(jí),市級(jí)后綴的數(shù)字得-1
if (result.code === value.pcode) {
result.number = (result.number - 1) + ''
}
if (result.number === '0') result.number = '全'
// 不僅要改list的number還要改對(duì)應(yīng)的checkedList上的number★~~~~~
if (this.checkedCityList.length !== 0) {
this.checkedCityList.forEach((redus, rIndex) => {
if (redus.code === result.code) {
this.checkedCityList[rIndex].number = result.number
}
})
}
})
} else {
// 如果當(dāng)前縣區(qū)級(jí)如果未被勾選
this.checkedAreaList.push({ code: value.code, pcode: value.pcode })
// 勾選時(shí)點(diǎn)擊當(dāng)前區(qū)縣地區(qū)時(shí)判斷當(dāng)前市級(jí)是否勾選,如果未勾選則勾選上(checked選擇狀態(tài)及高亮)
// 判斷當(dāng)前市級(jí)是否勾選
this.cityList.forEach((result, index) => {
// 找到對(duì)應(yīng)的市級(jí)
if (result.code === value.pcode) {
// 如果市級(jí)未勾選,則勾選上市級(jí)
if (result.checked === false) {
result.checked = true
result.number = '全'
this.checkedCityList.push({ code: value.pcode, pcode: '000000' })
//
}
// 到這一步肯定是被勾選上了
// 如果縣區(qū)被勾選,市級(jí)后綴的數(shù)字都得+1
if (result.number === '全') {
result.number = '1'
} else {
result.number = (result.number - 0 + 1) + ''
}
// 不僅要改list的number還要改對(duì)應(yīng)的checkedList上的number★~~~~~
if (this.checkedCityList.length !== 0) {
this.checkedCityList.forEach((redus, rIndex) => {
if (redus.code === result.code) {
this.checkedCityList[rIndex].number = result.number
}
})
}
}
})
}
console.log(this.checkedProvinceList, '省', this.checkedCityList, '市', this.checkedAreaList,'區(qū)縣')
// 改變當(dāng)前點(diǎn)擊的區(qū)縣高亮狀態(tài)
this.areaList[index].checked = !this.areaList[index].checked
}
}
}
</script>
<style lang="less">
.addressSelector{
main {
display: flex;
width: 100%;
background-color: #F5F5F5;
.provinceTree, .cityTree, .areaTree {
flex: 1;
height: 100vh;
border-right: 1.81rpx solid #E4E4E4;
overflow-y: auto;
.provinceBox, .cityBox, .areaBox {
position: relative;
height: 90.57rpx;
line-height: 90.57rpx;
text-align: center;
i {
position: absolute;
top: 30.8rpx;
right: 30.79rpx;
width: 28.98rpx;
height: 28.98rpx;
background-color: #188AFA;
border-radius: 50%;
line-height: 25.98rpx;
color: #FFFFFF;
font-size: 21.73rpx;
}
}
// 省級(jí)高亮樣式
.provinceHeightLight {
background: linear-gradient(270deg, #F5F5F5 0%, #D1E9FF 100%);
color: #188AFA;
}
// 市級(jí)高亮樣式
.cityHeightLight {
background-color: #F5F5F5;
color: #188AFA;
}
// 區(qū)縣高亮樣式
.areaHeightLight {
background-color: #F5F5F5;
color: #188AFA;
}
}
.cityTree, .areaTree {
background-color: #FFFFFF;
}
}
}
</style>
手撕小程序端多選級(jí)聯(lián)選擇器(地區(qū)多選選擇器)
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門慨蛙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辽聊,“玉大人,你說我怎么就攤上這事期贫「遥” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵通砍,是天一觀的道長(zhǎng)玛臂。 經(jīng)常有香客問我,道長(zhǎng)封孙,這世上最難降的妖魔是什么迹冤? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮虎忌,結(jié)果婚禮上泡徙,老公的妹妹穿的比我還像新娘。我一直安慰自己膜蠢,他們只是感情好锋勺,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狡蝶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贮勃。 梳的紋絲不亂的頭發(fā)上贪惹,一...
- 文/蒼蘭香墨 我猛地睜開眼寓搬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼珍昨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起句喷,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镣典,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后唾琼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兄春,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年锡溯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赶舆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哑姚。...
- 正文 年R本政府宣布宛乃,位于F島的核電站,受9級(jí)特大地震影響蒸辆,放射性物質(zhì)發(fā)生泄漏征炼。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一躬贡、第九天 我趴在偏房一處隱蔽的房頂上張望谆奥。 院中可真熱鬧,春花似錦拂玻、人聲如沸酸些。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)魄懂。三九已至,卻和暖如春闯第,著一層夾襖步出監(jiān)牢的瞬間市栗,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瀑粥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 官方是這樣描述picker的 普通選擇器有自帶三個(gè)必要屬性: 1、range 主要指服務(wù)端返回的數(shù)據(jù)集(也可自定義...
- miniprogram-picker已經(jīng)在Github開源卒密,并發(fā)布了npm包缀台。并寫了詳細(xì)的說明文檔和示例,歡迎各位...
- 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line)哮奇,也就是一...
- 在一些電商類的微信小程序中膛腐,地址選擇這個(gè)功能一般是必備的睛约,一般的收貨信息都需要有一個(gè)能選擇省市縣的控件,當(dāng)然也有些...