# DropDown 下拉筛选
该组件主要提供筛选下拉筛选框,内置基础筛选功能,可以根据自己的需求自定义筛选项。
兼容app-nvue,需要内置三个组件进行配合使用,uv-drop-down属于菜单项(其实还包括子组件uv-drop-down-item),uv-drop-down-popup属于筛选框。
只需要做简单的约定式配置,即可使用该功能,兼容性良好,已经在多端进行了多次测试。
# 平台兼容性
App(vue) | App(nvue) | H5 | 小程序 | VUE2 | VUE3 |
---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ |
# 基本用法
该用法只提供选择项及配置的方式和下拉框盒子,内容需要自己定义。
# uv-drop-down
- 设置
sign
属性,保证组件唯一性,如果一个项目用到多个该组件,就需要将每个sign
设置不同,组件内部使用了uni.$on监听,不设置可能会互相影响。uv-drop-down
和uv-drop-down-popup
组件都需设置且值必须相等。 - 设置
defaultValue
属性,默认值,如下设置[0,'0','all'],如果value等于0或'0'即代表该选项还未进行选择,即不是选中状态。
# uv-drop-down-item
- 设置
name
属性,选择项的字段标识,在处理逻辑的时候会用到。 - 设置
label
属性,展示选中或未选中的文本。 - 设置
value
属性,该项的值,如果不是defaultValue中的值,即是选中状态。 - 设置
type
属性,1 - 没有筛选项,表示是否选中,2 - 有多个筛选项。
<template>
<view style="height: 1000px;">
<uv-drop-down
ref="dropDown"
sign="dropDown_1"
:defaultValue="[0,'0','all']"
>
<uv-drop-down-item
name="order"
type="2"
label="综合排序"
value="all">
</uv-drop-down-item>
<uv-drop-down-item
name="type"
type="2"
label="文档格式"
value="0">
</uv-drop-down-item>
<uv-drop-down-item
name="vip_type"
type="1"
label='VIP文档'
:value="0">
</uv-drop-down-item>
</uv-drop-down>
<uv-drop-down-popup
sign="dropDown_1"
@popupChange="change"
>
<view style="width: 750rpx;height: 300rpx;background-color: #fff;"></view>
</uv-drop-down-popup>
</view>
</template>
<script>
export default {
onPageScroll() {
// 滚动后及时更新位置
this.$refs.dropDown.init();
},
methods: {
change(e){
console.log('弹窗打开状态:',e);
}
}
}
</script>
# 完整示例
使用内置筛选项,就需要根据约定参数,格式可以直接使用如下示例,每个参数的作用会在下方说明:
<template>
<view>
<uv-drop-down
ref="dropDown"
sign="dropDown_1"
text-active-color="#3c9cff"
:extra-icon="{name:'arrow-down-fill',color:'#666',size:'26rpx'}"
:extra-active-icon="{name:'arrow-up-fill',color:'#3c9cff',size:'26rpx'}"
:defaultValue="defaultValue"
:custom-style="{padding: '0 30rpx'}"
@click="selectMenu"
>
<uv-drop-down-item
name="order"
type="2"
:label="dropItem('order').label"
:value="dropItem('order').value">
</uv-drop-down-item>
<uv-drop-down-item
name="type"
type="2"
:label="dropItem('type').label"
:value="dropItem('type').value">
</uv-drop-down-item>
<uv-drop-down-item
name="vip_type"
type="1" label='VIP文档'
:value="dropItem('vip_type').value">
</uv-drop-down-item>
</uv-drop-down>
<uv-drop-down-popup
sign="dropDown_1"
:click-overlay-on-close="true"
:currentDropItem="currentDropItem"
@clickItem="clickItem"
@popupChange="change"
></uv-drop-down-popup>
</view>
</template>
<script>
export default {
onPageScroll() {
// 滚动后及时更新位置
this.$refs.dropDown.init();
},
computed: {
dropItem(name) {
return (name) => {
const result = {};
const find = this.result.find(item => item.name === name);
if (find) {
result.label = find.label;
result.value = find.value;
} else {
result.label = this[name].label;
result.value = this[name].value;
}
return result;
}
},
// 获取当前下拉筛选项
currentDropItem() {
return this[this.activeName];
}
},
data() {
return {
// 表示value等于这些值,就属于默认值
defaultValue: [0, 'all', '0'],
// 筛选结果
result: [{ name: 'order', label: '最新发布', value: 'new' }],
// { name: 'order', label: '最新发布', value: 'new' }
activeName: 'order',
order: {
label: '综合排序',
value: 'all',
activeIndex: 0,
color: '#333',
activeColor: '#2878ff',
child: [{
label: '综合排序',
value: 'all'
}, {
label: '最新发布',
value: 'new'
}, {
label: '低价优先',
value: 'money'
}]
},
type: {
label: '文档格式',
value: 'all',
activeIndex: 0,
color: '#333',
activeColor: '#2878ff',
child: [{
label: '全部',
value: 'all'
}, {
label: 'PDF',
value: 'pdf'
}, {
label: 'WROD',
value: 'word'
}, {
label: 'PPT',
value: 'ppt'
}]
},
vip_type: {
label: 'VIP文档',
value: 0,
activeIndex: 0
}
}
},
methods: {
change(e) {
console.log('弹窗打开状态:',e);
},
/**
* 点击每个筛选项回调
* @param {Object} e { name, active, type } = e
*/
selectMenu(e) {
const { name, active, type } = e;
this.activeName = name;
// type 等于1 的需要特殊处理:type不等于1可以忽略
if (type == 1) {
this.clickItem({
name: 'vip_type',
label: 'VIP文档',
value: e.active ? 1 : 0
});
} else {
const find = this.result.find(item => item.name == this.activeName);
if (find) {
const findIndex = this[this.activeName].child.findIndex(item => item.label == find.label && item.value == find.value);
this[this.activeName].activeIndex = findIndex;
} else {
this[this.activeName].activeIndex = 0;
}
}
},
/**
* 点击菜单回调处理
* @param {Object} item 选中项 { label,value } = e
*/
clickItem(e) {
// 下面有重新赋值,所以用let
let { label, value } = e;
const findIndex = this.result.findIndex(item => item.name == this.activeName);
if (this.defaultValue.indexOf(value) > -1 && this[this.activeName].label) {
label = this[this.activeName].label;
}
// 已经存在筛选项
if (findIndex > -1) {
this.$set(this.result, findIndex, {
name: this.activeName,
label,
value
})
} else {
this.result.push({
name: this.activeName,
label,
value
});
}
this.result = this.result.filter(item => this.defaultValue.indexOf(item.value) == -1);
uni.showModal({
content: `筛选的值:${JSON.stringify(this.result)}`
})
}
}
}
</script>
# 完整示例
# API
# DropDown Props
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
sign | String | Number | UVDROPDOWN | 组件唯一标识,需要手动传 |
default-value | Array | [0,'0','all'] | 默认值,表示参数value属于这里面的值,就说明是未选中即是默认展示的值。eg:上面示例中的{label: '全部',value: 'all'} 即是默认值。后续处理逻辑也可以根据是否是其中值进行过滤。 |
is-sticky | Boolean | true | 是否吸顶 |
text-size | String | 30rpx | 每项字体大小 |
text-color | String | #333 | 每项文本颜色 |
text-active-size | String | 30rpx | 每项选中状态字体大小 |
text-active-color | String | #3c9cff | 每项选中状态文本颜色 |
extra-icon | Object | {name: 'arrow-down', size: '30rpx', color: '#333'} | 每项右侧图标,暂时只支持设置默认值中的3个参数,参考 uv-icon (opens new window) |
extra-active-icon | Object | {name: 'arrow-up', size: '30rpx', color: '#3c9cff'} | 每项选中后右侧图标,暂时只支持设置默认值中的3个参数,参考 uv-icon (opens new window) |
# DropDownItem Props
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | String | Number | - | 字段标识 |
type | String | Number | - | 类型 1 没有筛选项,直接进行选中和不选中 2 有多个选项 |
label | String | - | 筛选的文本 |
value | String | Number | null | - | 筛选的值 |
is-drop | Boolean | false | 该项是否打开,可用于重置选项状态 |
# DropDownPopup Props
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
sign | String | Number | UVDROPDOWN | 组件唯一标识,需要手动传,与DropDown组件必须保持一致 |
z-index | String | Number | 999 | 弹出层的层级 |
opacity | String | Number | 0.5 | 遮罩层的透明度 |
click-overlay-on-close | Boolean | true | 是否允许点击遮罩层关闭弹窗 |
current-drop-item | Object | - | 当前下拉筛选菜单对象 |
key-name | String | label | 指定从当前下拉筛选菜单对象元素中读取哪个属性作为文本展示 |
# DropDown Events
事件名 | 说明 | 返回参数 |
---|---|---|
@selectMenu | 点击每项菜单回调 | { name, active, type } = e,active - 是否打开该项 |
# DropDownPopup Events
事件名 | 说明 | 返回参数 |
---|---|---|
@clickItem | 点击筛选回调处理 | { label, value } = e |
@popupChange | 打开关闭弹窗触发 | { show }=e,true或false |
# DropDown Methods
名称 | 说明 |
---|---|
init | 初始化弹窗的位置,在滚动时可以调用此方法,及时更新位置 |
# DropDownPopup Methods
名称 | 说明 |
---|---|
open | 打开弹窗 |
close | 关闭弹窗 |
# DropDownPopup Slots
名称 | 说明 |
---|---|
default | 默认插槽,完全自定义内容,包括逻辑都需自己写 |