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

手撕小程序端多选级联选择器(地区多选选择器),第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>

格式调整

界滚握面相关

***********************************************分割线*****************************************

标签

一、视图容器(View Container):

view 视图容器

scroll-view 可滚动视图容器

swiper 可滑动的视图容器

二、基础内容(Basic Content)

icon 图标

text 文字

progress 进度条

三、表单组件(Form)

button 按钮

form 表单

input 输入框

checkbox 多散旁项选择器

radio 单项选择器

picker 列表选择器

slider 滑动选择器

switch 开关选择器

label 标签

四、 *** 作反馈组件(Interaction)

action-sheet 上拉菜单

modal 模态d窗

progress 进度条

toast 短通知

五、导航(Navigation)

navigator 应用内跳转

六、多媒体(Media)

audio 音频

image 图冲备橡片

video 视频

七、地图(Map)

map 地图

八、画布(Canvas)

canvas 画布


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存