手撕小程序端多选级联选择器(地区多选选择器)

手撕小程序端多选级联选择器(地区多选选择器),第1张

// 鉴于市面上没有好用的移动端多选级联选择器,自己手写了一个

// 地区选择器

<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 {

// 省级城市编码

pcode: '',

// 市级城市编码

ccode: '110000',

// 省份列表

provinceList: [],

// 市级列表

cityList: [],

// 区县列表

areaList: [],

// 存储选中的省份列表

checkedProvinceList: [],

// 存储选中的市级列表

checkedCityList: [],

// 存储选中的区县级列表

checkedAreaList: []

}

},

onShow() {

// 获取省份列表

this.getProvinceList().then(() =>{

// 获取默认市级列表

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'})

// 设置默认值

this.cityList = []

res.data.list.forEach((item, index) =>{

this.cityList.push({

id: item.id, // 地区id

name: item.name, // 地区名称

code: item.code, // 地区编码

pcode: item.pcode, // 父级地区编码

checked: false, // 选择状态

switch: false, // 切换状态

number: '', // 子级选中的值

index: index // 当前地区的下标

})

})

// 2.市级高亮

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.直接将所有区县级列表清空

this.areaList = []

// 4.将所有省份switch改为false,同时将当前选中的省份switch改为true

this.provinceList.forEach(zResult =>{

zResult.switch = false

})

this.provinceList[index].switch = true

return false

// 如果当前省级已经被点击过,但是不是第一次点击时

} else if (alreadyCheck === true &&value.switch === true) {

// 除了移除省级code还要移除对应省级下的所有市级code(移除对应的高亮状态,默认会重置)

// 将省级code和市级级pcode比较如果相同则移除(第一层)

if (this.checkedCityList.length !== 0) {

// --------------移除对应的市级code

let newCheckedCityList = []

this.checkedCityList.forEach((val, index) =>{

if (value.code !== val.pcode) {

newCheckedCityList.push(val)

} else {

// 将对应的市级code和区县级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,'区县')

// 改变当前点击的省份高亮状态

this.provinceList[index].checked = !this.provinceList[index].checked

// 改变当前点击省份的全选状态

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'})

// 设置默认值

this.areaList = []

res.data.list.forEach((item, index) =>{

this.areaList.push({

id: item.id, // 地区id

name: item.name, // 地区名称

code: item.code, // 地区编码

pcode: item.pcode, // 父级地区编码

checked: false, // 选择状态

switch: false, // 切换状态

number: '', // 子级选中的值

index: index // 当前地区的下标

})

})

// 2.区县高亮

this.checkedAreaList.forEach((checkArea, checkIndex) =>{

this.areaList.forEach((allArea, allIndex) =>{

if (checkArea.code === allArea.code) {

this.areaList[allIndex].checked = true

}

})

})

// 3.将所有市级switch改为false,同时将当前选中的市级switch改为true

this.cityList.forEach(zResult =>{

zResult.switch = false

})

this.cityList[index].switch = true

return false

// 如果当前市级已经被点击过,但是不是第一次点击时

} else if (alreadyCheck === true &&value.switch === true) {

this.checkedCityList.splice(alreadyIndex, 1)

// 除了移除市级code还要移除对应市级下的所有区县级code同时移除对应的高亮状态

// 将市级code和区县级pcode比较如果相同则移除

if (this.checkedAreaList.length !== 0) {

let newCheckedAreaList = []

this.checkedAreaList.forEach((val, index) =>{

if (value.code !== val.pcode) {

newCheckedAreaList.push(val)

}

})

this.checkedAreaList = newCheckedAreaList

}

// 当市级已经被勾选时,找到对应的省级,省级后缀的数字得-1

this.provinceList.forEach((result, index) =>{

if (result.code === value.pcode) {

result.number = (result.number - 1) + ''

}

if (result.number === '0') result.number = '全'

// 不仅要改list的number还要改对应的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: '全' })

// 勾选时点击当前市级地区时判断当前省级是否勾选,如果未勾选则勾选上(checked选择状态及高亮)

// 判断当前省级是否勾选

this.provinceList.forEach((result, index) =>{

// 找到对应的省级

if (result.code === value.pcode) {

// 如果省级未勾选,则勾选上省级

if (result.checked === false) {

result.checked = true

result.number = '全'

this.checkedProvinceList.push({ code: value.pcode, pcode: '000000', number: '1' })

}

// 到这一步肯定省级肯定是被勾选上了

// 如果市级被勾选,省级后缀的数字都得+1

if (result.number === '全') {

result.number = '1'

} else {

result.number = (result.number - 0 + 1) + ''

}

// 不仅要改list的number还要改对应的checkedList上的number★~~~~~

if (this.checkedProvinceList.length !== 0) {

this.checkedProvinceList.forEach((redus, rIndex) =>{

if (redus.code === result.code) {

this.checkedProvinceList[rIndex].number = result.number

}

})

}

}

})

}

// 改变当前点击的市级高亮状态

this.cityList[index].checked = !this.cityList[index].checked

// 改变当前点击市级的全选状态

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,'区县')

const { data: res } = await addressPartListApi(this.ccode)

if (res.code !== 0) return this.$refs.uTips.show({ title: res.msg, type: 'error', duration: '2000'})

// 设置默认值

this.areaList = []

res.data.list.forEach((item, index) =>{

this.areaList.push({

id: item.id, // 地区id

name: item.name, // 地区名称

code: item.code, // 地区编码

pcode: item.pcode, // 父级地区编码

checked: false, // 选择状态

switch: false,// 切换状态

index: index // 当前地区的下标

})

})

// ------------------------------------------------------------------------------------------------(再获取完区县级列表后点击市级重置区县级高亮)

// 用所有被勾选的区县级code和所有区县列表进行比较如果相同则高亮

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

}

})

})

}

},

// 点击区县触发

clickAreaList(value, index) {

// 存储被点击的区县code(判断如果已经存在被点击过则去除)

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

}

})

}

// 如果当前县区级已经被勾选则去除

if (alreadyCheck === true) {

this.checkedAreaList.splice(alreadyIndex, 1)

// 去除的时候市级肯定是勾选状态

this.cityList.forEach((result, index) =>{

// 找到对应的市级,市级后缀的数字得-1

if (result.code === value.pcode) {

result.number = (result.number - 1) + ''

}

if (result.number === '0') result.number = '全'

// 不仅要改list的number还要改对应的checkedList上的number★~~~~~

if (this.checkedCityList.length !== 0) {

this.checkedCityList.forEach((redus, rIndex) =>{

if (redus.code === result.code) {

this.checkedCityList[rIndex].number = result.number

}

})

}

})

} else {

// 如果当前县区级如果未被勾选

this.checkedAreaList.push({ code: value.code, pcode: value.pcode })

// 勾选时点击当前区县地区时判断当前市级是否勾选,如果未勾选则勾选上(checked选择状态及高亮)

// 判断当前市级是否勾选

this.cityList.forEach((result, index) =>{

// 找到对应的市级

if (result.code === value.pcode) {

// 如果市级未勾选,则勾选上市级

if (result.checked === false) {

result.checked = true

result.number = '全'

this.checkedCityList.push({ code: value.pcode, pcode: '000000' })

//

}

// 到这一步肯定是被勾选上了

// 如果县区被勾选,市级后缀的数字都得+1

if (result.number === '全') {

result.number = '1'

} else {

result.number = (result.number - 0 + 1) + ''

}

// 不仅要改list的number还要改对应的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,'区县')

// 改变当前点击的区县高亮状态

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

}

}

// 省级高亮样式

.provinceHeightLight {

background: linear-gradient(270deg, #F5F5F5 0%, #D1E9FF 100%)

color: #188AFA

}

// 市级高亮样式

.cityHeightLight {

background-color: #F5F5F5

color: #188AFA

}

// 区县高亮样式

.areaHeightLight {

background-color: #F5F5F5

color: #188AFA

}

}

.cityTree, .areaTree {

background-color: #FFFFFF

}

}

}

</style>

小程序官网关于picker的介绍

小程序官网提供了5中选择器,分别是:

普通选择器

多列选择器

时间选择器

日期选择器

省市区选择器

以下仅列举省市区选择器的用法:

index.wxml

index.js

多看文档,不然又要自己封装了。。。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11257561.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存