在数据密集型的后台系统中,筛选条件的数量往往随着业务复杂度呈指数级增长。我曾参与过一个电商数据分析平台的重构,当筛选条件膨胀到23项时,传统的展开/收起模式导致用户需要反复点击按钮才能找到目标条件,操作热力图显示超过60%的用户会因此放弃使用高级筛选功能。这正是TQueryCondition组件推出「下拉展示更多条件」功能的现实背景——它不仅仅是一个UI改进,更是对复杂系统人机交互模式的深度重构。
当筛选条件超过10个时,前端工程师通常面临三种布局方案的选择:
传统展开/收起模式
选项卡分组模式
ts复制const tabGroups = [
{ label: '基础条件', fields: ['name', 'status'] },
{ label: '高级条件', fields: ['priceRange', 'salesVolume'] }
]
下拉动态勾选模式(本文方案)
vue复制<t-query-condition
:is-drop-down-select-more="true"
:more-check-list="dynamicConditions"
/>
通过对比测试发现,在条件数量超过15个的场景下,第三种方案的查询完成时间比传统模式快42%,且用户满意度提升27%。其核心优势在于:
实际项目中选择方案时,建议根据Nielsen Norman Group的「7±2法则」:当条件超过9个时,就应该考虑动态收纳方案。
启用下拉展示功能需要设置两个关键参数:
ts复制const opts = {
isDropDownSelectMore: true, // 启用下拉模式
moreCheckList: [ // 可动态管理的条件池
{ label: '商品SKU', prop: 'sku', comp: 'el-input' },
{ label: '供应商', prop: 'supplier', comp: 'el-select' }
]
}
参数对照表:
| 参数名 | 类型 | 必需 | 说明 |
|---|---|---|---|
isDropDownSelectMore |
Boolean | 是 | 总开关,启用下拉模式 |
moreCheckList |
Array | 是 | 所有可选条件的配置数组 |
popoverAttrs |
Object | 否 | 控制下拉弹窗的样式和行为 |
defaultVisibleCount |
Number | 否 | 默认展示的条件数量 |
每个条件项支持Element Plus全系列组件的配置继承:
ts复制{
label: '价格区间',
prop: 'priceRange',
comp: 'el-input-range', // 支持自定义组件
bind: { // 组件原生属性
min: 0,
max: 10000,
step: 100
},
eventHandle: { // 事件监听
change: (val) => console.log(val)
}
}
特殊处理场景:
isSelfCom: truebind设为函数:ts复制bind: (formData) => ({
options: fetchOptions(formData.category)
})
在CRM系统中,我们实现了根据用户角色动态加载条件:
ts复制watchEffect(() => {
const role = store.state.user.role
opts.moreCheckList = baseConditions.concat(
role === 'admin' ? adminConditions : []
)
})
通过localStorage保存用户的条件选择状态:
ts复制const saveConditionPref = (checkedItems) => {
localStorage.setItem(
'filterPref',
JSON.stringify(checkedItems.map(item => item.prop))
)
}
// 初始化时读取
if (localStorage.getItem('filterPref')) {
state.visibleConditions = opts.moreCheckList.filter(item =>
JSON.parse(localStorage.filterPref).includes(item.prop)
)
}
当条件数量超过50个时,建议:
使用虚拟滚动优化下拉菜单:
vue复制<el-select-v2
v-model="selectedConditions"
:options="filteredOptions"
/>
实现条件的分批加载:
ts复制const loadMore = () => {
if (scrollBottom) {
visibleCount.value += 10
}
}
实现「选择省份后才显示城市选择器」的效果:
ts复制const provinceChange = (val) => {
const cityField = opts.moreCheckList.find(item => item.prop === 'city')
cityField.bind.disabled = !val
// 自动清除已选城市
if (!val) form.city = null
}
动态条件的验证需要额外处理:
vue复制<el-form-item
v-for="item in visibleConditions"
:prop="item.prop"
:rules="item.required ? [{ required: true }] : []"
>
<!-- 动态组件 -->
</el-form-item>
通过CSS媒体查询调整布局:
css复制@media (max-width: 768px) {
.t-query-condition {
grid-template-columns: repeat(2, 1fr);
}
.dropdown-trigger {
width: 100%;
}
}
在最近的数据中台项目中,这套方案成功将筛选区域的点击率提升了35%,同时减少了80%的页面横向滚动操作。一个值得分享的细节是:我们为高频条件添加了可视化标记(如🔥图标),进一步提升了功能发现性。