# 动态搜索组件
**Repository Path**: wcf_dqc/dynamic-search-component
## Basic Information
- **Project Name**: 动态搜索组件
- **Description**: 动态搜索组件
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-02-16
- **Last Updated**: 2023-02-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 动态搜索组件
#### 介绍
我们来看一张图:

从这张图中我们不难发现有两个问题
1. 搜索条件过多,可以肯定大部分条件不常用甚至用不到
2. 列表表头字段过多,有些肯定也是我们不常关注的。但是偶尔会关注一下
我们都知道一般情况下一个正常人是不会同时输入那么多条件去查数据的。所以当一个用户打开这个页面时看到这么多的搜索条件时,估计都直接吐了吧。功能虽然能用,但是页面奇丑无比。
当然这些条件都是用户让加上去的。虽然这是用户的需求,但是对于我们开发来说就显得有点乏味了,每个页面都需要写很多的输入框,而且js也没少写多少,感觉有点智障。于是我在思考能不能优化一下,让每个用户自己决定需要的搜索条件,自己控制列表表头字段的显示和隐藏以及控制表头字段的排列顺序。这样页面既美观又能达到用户的需求。为此我研究了一个 动态搜索组件以及实现列表表头动态显示以及排列的功能。该组件最终的目的是减少页面代码,优化页面布局,给用户一个好的使用体验。
最终的效果如下:
1. 自定义搜索字段

2. 搜索条件都放开

3. 显示部分表头字段

4. 可以拖动工单号到工单类型前,列表中会发生对应的变化
5. 也可以拖动搜索字段改变位置
#### 动态搜索组件优点:
1. 使用组件不再需要写大量的搜索输入框
2. 每个用户可以自己选择需要的搜索条件
3. 不需要修改Api
4. 通过拖动改变搜索框的顺序
#### 列表表头动态渲染功能优点:
1. 在表头字段较多的情况下不需要写大量的html代码
2. 通过拖动改变表头字段的排列顺序
#### 软件架构
vue + element ui
#### 使用说明
1. 全局注册组件
```vue
// 全局注册列表搜索及列头相关组件
import dynamicSearchs from './components/baseDynamicSearchs/dynamic-searchs.vue'
import draggableTableHeards from '@/components/baseDynamicSearchs/draggable-table-heards.vue'
import searchFieldSettings from '@/components/baseDynamicSearchs/search-field-settings.vue'
Vue.component('dynamicSearchs', dynamicSearchs);
Vue.component('draggableTableHeards', draggableTableHeards);
Vue.component('searchFieldSettings', searchFieldSettings);
```
2. 安装可拖动插件
```vue
yarn add vuedraggable
npm i -S vuedraggable
```
1. 开始使用组件
**搜索组件:**
```vue
```
条件说明:
* dynamicSearch 为搜索条件对象
* searchQuery 为接口查询参数 它是一个对象
* enterSearch 自定义回车事件
* changeSearch 自定义改变事件
* handleFilter 为搜索方法
**列表表头动态加载:**
```vue
{{ scope.row[scope.column.property] ? "是" : "否" }}
{{ scope.row[scope.column.property] }}
```
2. 准备必要条件
```vue
export default {
data() {
return {
// 搜索条件,除了分页条件外,其他的搜索条件自动生成
searchQuery: {
skipCount: 0,
maxResultCount: 20,
Sorting: "CreationTime DESC",
},
// 预定义动态查询所有字段
dynamicSearch: {
models: [
{
key: "name",//对应后端搜索条件的字段-必须是接口支持的字段
value: null,// 输入框的值
inputBoxType: 1,// 文本框类型
placeholder: "请输入姓名",// 文本框的placeholder属性
description: "姓名",//用于设置按钮中显示的名称
isShow: true,// 显示隐藏
selectValue: [],// 如果inputBoxType为3或者6时必须写
apiAddress: '',// 如果inputBoxType为3或者6时必须写。后端返回下拉框数据的接口
optionLabel: 'name',// 如果inputBoxType为6时自定义下拉数据的label数据原
optionValue: 'key',// 如果inputBoxType为6时自定义下拉数据的label数据原
},
...
],
},
// 预定义表头所有字段
tableHeard: {
columns: [
{
label: "名称",// 用于表头显示和设置按钮中显示的名称
key: "name",// 用于匹配循环中的Key -- 必须是接口返回的字段
isShow: true,// 是否显示
// 上边这三个属性是必须的,下边的可以根据element ui 需要自定义
width: 150,// 列的长度
sortTable:"custom" // 是否可排序
},
{
label: "是否启用",// 用于表头显示和设置按钮中显示的名称
key: "isUsed",// 用于匹配循环中的Key
isShow: true,// 是否显示
// 上边这三个属性是必须的,下边的可以根据element ui 需要自定义
width: 150,// 列的长度
sortTable:"custom" // 是否可排序
},
...
],
},
};
},
created() {
this.getList();
},
methods: {
//操作栏表头放置设置按钮
initSetButtons(h, { column, $index }) {
return (
)
},
// 获取表格数据--这只是示例,并不能运行,请根据实际情况运行
getList() {
this.tableLoading = true;
api.getList(this.searchQuery)
.then((res) => {
this.tableLoading = false;
if (res.data.success) {
this.tableData = res.data.result.items;
this.totalCount = res.data.result.totalCount;
}
})
.catch(() => {
this.tableLoading = false;
});
},
// 查询
handleFilter() {
this.currentPage = 1;
this.searchQuery.skipCount = 0;
this.getList();
},
},
};
```
5. 相关条件说明
> **inputBoxType 所有值说明**:
>
> - 1 文本框
> - 2 数值框
> - 3 下拉选择框
> - 4 Boolean类型下拉选择框
> - 5 DateTime类型框
> - 6 下拉选择,可自定义option中的vale和label
> - 7 Date 类型框
> - 其他条件可自行在dynamic-searchs.vue 组件中扩展或修改
>
> **如果 inputBoxType = 3 时:**
>
> - apiAddress 为后端返回下拉框数据的接口。接口的数据结构为一个包含 Id和name的对象的集合
>
> - apiAddress 为空时,selectValue必须构建包含 Id和name的对象的集合
>
> ```vue
> {
> inputBoxType: 3,
> apiAddress: 'api/getAllStatus',
> selectValue: [],
> }
> ```
>
> ```vue
> {
> inputBoxType: 3,
> apiAddress: '',
> selectValue: [
> {
> id:1,
> name:'进行中'
> },{
> id:2,
> name:'已完成'
> },
> id:3,
> name:'已删除'
> }
> ],
> }
> ```
>
> **如果 inputBoxType = 6 时:**
>
> - 示例
>
> ```vue
> {
> inputBoxType: 6,
> apiAddress: 'api/getAllStatus',
> selectValue: [],
> optionLabel: 'name',
> optionValue: 'name',
> }
> ```
>
> - 有时候我们的下拉框条件不一定需要的时Id,而就是需要通过选中的名称去查询时
>
> ```vue
> {
> inputBoxType: 6,
> apiAddress: '',
> selectValue: [
> {
> id:1,
> name:'进行中'
> },{
> id:2,
> name:'已完成'
> },
> id:3,
> name:'已删除'
> }
> ],
> optionLabel: 'name',
> optionValue: 'name',
> }
> ```
6. 温馨提示:
在使用组件时需要注意组件内引用的文件路径是否正确。比如
```vue
// 根据实际情况引入
import * as dynamicSearch from "@/api/baseDynamicSearchs/index.js";
// 比如使用 apiAddress 时可能会出现问题的地方
import request from "@/lib/ajax.ts";
// 获取动态加载的数据
export function GetDynamicSelectTemp(url, params) {
return request({
url: url,
method: "get",
params,
});
}
```
**最后:**
希望该组件也能帮助到你。如有不合理的地方还希望大家多多提意见。