组件背景
在编写项目时(特别是办公类项目),列表页面至少占据了70%左右UI开发。过程中一定会碰到两种情况:
- 查询条件很少
- 查询条件很多
当碰到查询条件很多的情况下,在小屏幕时,就会出现,可视范围都是查询条件,而没有列表信息。如下图:
这是多么【难受】的事情啊。所以需要写一个列表查询组件去适配项目中的各种情况。
前言
- 技术栈:vu3 + element ui plus + ts
- 说在前面:这个控件需要分多篇来描述,因为内容有点多。
先看效果
-
效果一:
-
效果二:
-
效果三:
设计
- 设计的愿景:
- 组件能够适配条件多的和条件少的各种情况。
- 开发人员的使用心智负担不会因为条件多少而变化,使用的风格一致。
- 控件布局:
- 组件需要考虑如何快速的适配布局
- 组件需要考虑如何控制在页面中的显示占比
- 控件支持:
-
组件需要支持默认的常用控件UI
-
组件需要考虑如何动态扩展
设计的愿景
- 基于第一点,控件配置了三种模式:
- 默认全部显示;
- 默认显示一行,但可以收起和展开其他的条件;
- 默认显示关键条件,通过弹层显示所有的条件。
通过效果图,可以了解到这边的愿景,被很好的实现了。
控件布局
- 通过【设计愿景】能够很好的解决显示占比的问题
- 适配布局这点,通过学习 element ui中的控件 【# Descriptions 描述列表】的属性【column】。从而实现一行显示几个查询条件来完成。
控件支持
-
因为控件使用Json的模式配置,目前支持了一些常用的控件。支持列表如下:
参数 说明 Autocomplete 自动补全输入框 SelectMultiple 下拉多选控件 Select 下拉选择控件 Input 输入框 DatePicker 日期选择,不带时间 DateTime 日期选择,带时间 DateRangePicker 日期范围选择,不带时间 DateTimeRangePicker 日期范围选择,带时间 -
动态扩展
目前并未实现
用法说明
以弹窗显示为例
设置控件属性type='hidden'。一般当查询的条件特别多,如果在列表页面显示,明显影响页面的优雅性时,使用该控件。
::: 样例代码
<template>
<div>
<SpTableSearch
:type="'hidden'"
:model="searchForm"
:searchItems="itemsConfig"
:labelPosition="'top'"
@searchEvent="searchData"
@resetDataEvent="resetData"
>
</SpTableSearch>
</div>
</template>
<script>
// import { SpTableSearch } from '@sp/pc-ui'
import { defineComponent, reactive } from 'vue'
export default defineComponent({
setup() {
const searchData = (data: any) => {
console.log('改变的数据:', data)
}
const resetData = (data: any) => {
console.log('重置的数据:', data)
}
const handleSelect = (item: RestaurantItem) => {
console.log('autocomplete:', item)
}
const searchForm = reactive({
fieldName: '',
fieldKey: '',
state: '',
})
const itemsConfig = reactive([
{
label: '名称',
prop: 'fieldName',
uiType: 'Input',
placeholder: '请输入名称',
hiddenItem: true,
},
{
label: '标识',
prop: 'fieldKey',
uiType: 'Input',
placeholder: '请输入标识',
hiddenItem: true,
},
{
label: '前端技术',
prop: 'state',
uiType: 'Autocomplete',
autocompleteData: [
{ value: 'vue', link: 'https://github.com/vuejs/vue' },
{ value: 'element', link: 'https://github.com/ElemeFE/element' },
{ value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
{ value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
{ value: 'vuex', link: 'https://github.com/vuejs/vuex' },
{ value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
{ value: 'babel', link: 'https://github.com/babel/babel' },
],
autocompleteSelect: handleSelect,
},
])
return {
searchForm,
itemsConfig,
searchData,
resetData,
handleSelect,
}
},
})
</script>
<style lang="less"></style>
控件属性说明
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 必填 |
|---|---|---|---|---|---|
| type | 控件类型 | string 或 ShowTypes | 'default'/'oneLine'/'hidden' | 'default' | 否 |
| model | 控件绑定的数据对象 | Object | {} | {} | 是 |
| column | 一行显示几列 | number | 1-10 | 2 | 否 |
| labelPosition | label 显示的位置 | string 或 LabelPositionTypes | 'left'/'right'/'top'/'topBorder' | 'right' | 否 |
| labelWidth | label 的宽度 | string | '1px'-'Npx' | '100px' | 否 |
| searchItems | 配置查询控件集合 | SearchItemProps[] | [] | [] | 是 |
| contentStyle | 控件的样式 | string | 样例: :contentStyle="'padding-left:20px;'" | '' | 否 |
控件事件
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| searchEvent | 查询触发 | Function | ()=>{} | 否 |
| resetDataEvent | 重置数据触发 | Function | ()=>{} | 否 |
控件方法
| 参数 | 说明 | 类型 | 使用范围 | 必填 |
|---|---|---|---|---|
| closeExpandStatus | 收起展开 | Function | type==='hidden' | 否 |
| getExpandStatus | 获取是否展开 | Function | type==='oneLine' | 否 |
ShowTypes
| 参数 | 说明 |
|---|---|
| default | 默认使用 |
| oneLine | 一行显示 |
| hidden | 隐藏显示 |
LabelPositionTypes
| 参数 | 说明 |
|---|---|
| left | label 显示在左侧 |
| right | label 显示在右侧 |
| top | label 显示在顶部 |
| topBorder | label 显示顶部边框上 |
SearchItemProps 查询控件的配置
结语
后面会再写一篇,在下一篇中会给出具体的实现代码,以及代码的设计思路。
在开发的过程中,发现某些事情,让你的开发特别不舒服的时候,就是组件、工具、插件等的开发需求产生的时候。不知道各位看客是否有同样的感受。
就像我前面写【swagger2-to-ts】这个工具一样,就是因为跟后端对接写ts的entity太无聊了。