uniapp + uview 下拉筛选
新建组件文件夹selectDownBox
<!-- classFilter.vue -->
<template>
<view>
<view v-for="(emi,e) in proList" :key="e">
<view @click="showChildList(e)" :ref="'classBox' + e" class="drop-item" :style="{'color':isActive[e]? '#2979ff' : '#909399','padding-left': nodes * 25 + 'rpx'}">
{{emi[emiName]}}
<u-icon v-if="emi.children" :name="scopesDefault[e] ? 'arrow-down' : 'arrow-right'" size="15"
:color="scopesDefault[e] ? '#2979ff' : '#909399'" class="ml-8">
</u-icon>
<u-icon v-if="isActive[e]" name="checkbox-mark" size="15" color="#2979ff" style="position: absolute;right: 50rpx;"></u-icon>
</view>
<u-line></u-line>
<template v-if="emi.children">
<class-filter v-on="$listeners" :nodes="nodes + 1" v-if="scopesDefault[e]" :proList="emi.children"
:emiName="emiName" :dtitle="dtitle">
</class-filter>
</template>
</view>
</view>
</template>
<script>
export default {
name: 'classFilter',
props: {
proList: {
type: Array,
default () {
return []
}
},
emiName: {
type: String,
default: 'no'
},
dtitle: {
type: String,
default: 'no'
},
nodes:{
type:Number,
default:0
}
},
data() {
return {
scopesDefault: [],
scopes: [],
isActive: []
}
},
mounted() {
this.init()
},
methods: {
init() {
this.proList.forEach((item, index) => {
this.scopesDefault[index] = false;
this.$set(this.isActive, index, item[this.emiName] === this.dtitle)
if (item.children) {
this.scopes[index] = true;
} else {
this.scopes[index] = false;
}
})
},
showChildList(e) {
if (this.scopes[e]) {
if (this.scopesDefault[e]) {
this.$set(this.scopesDefault, e, false);
} else {
this.scopesDefault.map((item, index) => {
this.$set(this.scopesDefault, index, index === e)
})
}
} else {
this.$set(this.isActive, e, true)
this.$emit('getClass', this.proList[e])
}
}
}
}
</script>
<style scoped lang="scss">
</style>
<!-- sekectDown.vue -->
<template>
<view class="position-relative w-100">
<view class="w-100 d-flex a-center class-btn">
<u-button class="flex-1" v-for="(menu,m) in refMenu" :key="m" :text='menu.dTitle'
:type="menu.active ? 'primary' : 'info'" :plain="true" :size="btnSize" shape='circle'
:icon="showDrop && menu.active ? 'arrow-down-fill' : 'arrow-up-fill'" @click="menuOpen(m)"></u-button>
</view>
<u-overlay :show="showDrop" style="top: 200rpx;" :style="[popupStyle]">
<block v-if="!$slots.default && !$slots.$default">
<view class="w-100 bg-white">
<template v-if="refMenu[current] && refMenu[current][keyPro]">
<scroll-view scroll-y style="max-height: 60vh;">
<class-filter :ref="'class'+refMenu[current][keyPro]" :dtitle='refMenu[current].dTitle'
:proList="refMenu[current][listName]" emiName="classificationName"
@getClass="textClass"></class-filter>
</scroll-view>
</template>
</view>
</block>
<slot v-else></slot>
</u-overlay>
</view>
</template>
<script>
import classFilter from '@/components/selectDown/classFilter.vue'
export default {
props: {
title: {
type: String,
default: 'title'
},
menuList: {
type: Array,
default () {
return []
}
},
listName: {
type: String,
default: undefined
},
btnSize: {
type: String,
default: 'small'
},
proper: {
type: String,
default: 'proper'
},
duration: {
type: Number,
default: 300
},
keyPro: {
type: String,
default: 'keyPro'
}
},
components: {
classFilter
},
computed: {
popupStyle() {
let style = {};
style['transition-duration'] = this.duration / 1000 + 's';
return style;
}
},
data() {
return {
isChose: false,
showDrop: false,
current: 9999,
liList: [],
refMenu: []
}
},
mounted() {
this.refMenu = JSON.parse(JSON.stringify(this.menuList))
this.refMenu.map(item => {
this.$set(item, 'dTitle', item[this.title])
this.$set(item, 'active', false)
})
},
methods: {
menuOpen(m) {
if (m === this.current && this.showDrop) {
this.showDrop = false
} else {
this.showDrop = true
this.refMenu.map((item, index) => {
this.$set(item, 'active', index === m)
})
this.current = m
this.liList = this.menuList[m][this.listName]
}
},
closeDrop(ob) {
setTimeout(() => {
this.showDrop = false
this.$emit('menuClick', ob)
}, this.duration)
},
textClass(da) {
console.log('textClass(da)', da)
this.refMenu[this.current].dTitle = da.classificationName
this.refMenu[this.current].active = false
let ob = {
keyPro: this.refMenu[this.current][this.keyPro],
value: da.id
}
this.closeDrop(ob)
}
}
}
</script>
<style scoped lang="scss">
.class-btn{
::v-deep .u-icon--right {
position: absolute;
right: 20rpx;
}
::v-deep .u-button__text{
line-height: 1;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
width: 75%;
}
}
</style>
使用
<select-down-box ref="selectBox" :menuList="droList" listName="selectList" keyPro="type" title="name" proper="label" @menuClick="chDrownItem"></select-down-box>
import selectDownBox from '@/components/selectDown/selectDown.vue'
const droList = [
{
name: '分类1',
type: 'tj',
selectList: [{
children: null,
id: "1111111",
classificationName: "子分类"
},
{
children: null,
id: "1111111",
classificationName: '子分类'
},
{
children: null,
id: "1111111",
classificationName: '子分类'
}
]
},
{
name: '分类2',
type: 'tj2',
selectList: [{
children: [{children: null,classificationName: "子分类测试嘎嘎22",classificationSort: "3"}],
id: "1111111",
classificationName: "子分类"
}
]
}
]
const chDrownItem = function(da) { console.log(da) }