前情提要
使用elementui
的 el-table
和 el-pagination
搭建分页表格数据,想要实现不同的搜索功能,跟后端一样,类似下图显示:
image.png
搜索区域可以根据不同的搜索条件进行匹配,条件:
= | > | >= |<= | 是否为空(IS_UNDEF) | like | left_like | right_like | in | 日期范围(DBT)
搜索的字段类型:
日期、数字、字符串
实现方法
思考:
主要思考难点是怎么让数据保持存在且不显示?
可以利用数据的 双向绑定属性 实现,这里为_hide
,为true
则不显示,反之,则显示。
匹配的代码大概如下:
// 前端搜索(简版)
handleDataSearch(queryParams) {
// 表单列表-查询字段
const conditions = [{......}]
const subData = this.data
if (subData && subData.length < 1) return
for (let i = 0; i < subData.length; i++) {
this.$set(subData[i], '_hide', false)
}
conditions.forEach(cond => {
if (
!cond.hasOwnProperty('searchType') ||
cond.searchType.indexOf('precise') != -1
) {
const { ct, qt, name, colPrefix, option } = cond
const op = this.getQT(qt) // 获取不同的条件值
const path = 'Q$' + colPrefix + name + '$' + op
let val = queryParams.fieldLogic[path]
if (ct == 'number_range') { // 数字范围,两个分开匹配
const lVal =
queryParams.fieldLogic[`Q$${colPrefix + name}$GE`]
const rVal =
queryParams.fieldLogic[`Q$${colPrefix + name}$LE`]
this.doMatch(subData, lVal, 'GE', name, cond)
this.doMatch(subData, rVal, 'LE', name, cond)
} else {
this.doMatch(subData, val, op, name, cond)
}
}
})
},
// 用 正则表达式 进行匹配
doMatch(arr, value, op, code, field) {
const isDef = v => {
return v !== undefined && v !== null && v !== ''
}
if (!isDef(value)) return // 没有值输入时,不匹配
const { ct, ty } = field
if (ct == 'onetext' && ['为空', '不为空'].indexOf(value) > -1) {
op = 'IS_UNDEF'
} else if (
(['number'].indexOf(ct) > -1 || ty == 'number') &&
typeof value === 'string' &&
value.length
) {
value = +value
} else if (op == 'IN' && value instanceof Array) {
value = value.join(',')
} else if (op === 'DBT' && typeof value === 'string') {
value = value.split(',')
}
for (let i = 0; i < arr.length; i++) {
let v = arr[i][code]
if (
op !== 'IS_UNDEF' &&
(['number'].indexOf(ct) > -1 ||
ty == 'number') &&
typeof v === 'string' &&
v.length
) {
v = +v
}
let _hide = false
// 没有定义值时统一不符合筛选标准,除非是 '为空' || '!=' 判断
switch (op) {
case 'SE': // '='
case 'S': // '='
_hide = !(v === value)
break
case 'NE': // '!='
_hide = v === value
break
case 'DS':
case 'SLL': // 'left_like'
_hide = v ? !new RegExp('^' + value).test(v) : true
break
case 'SLR': // 'right_like'
_hide = v ? !new RegExp(value + '$').test(v) : true
break
case 'DYIN':
case 'IN':
_hide = v ? !new RegExp(v).test(value) : true
break
case 'DGR':
case 'GT': // '>'
_hide = !(v > value)
if (
('date' == ct || 'DGR' == op) &&
!_hide &&
v.length > value.length
) {
_hide = !(v.slice(0, value.length) > value) // 日期长度不一致时
}
break
case 'DLE':
case 'LT': // '<'
_hide = isDef(v) ? !(v < value) : true
break
case 'DL':
case 'GE': // '>='
_hide = isDef(v) ? !(v >= value) : true
break
case 'DG':
case 'LE': // '<='
_hide = isDef(v) ? !(v <= value) : true
if (('date' == ct || 'DG' == op) && _hide) {
_hide = !new RegExp('^' + value).test(v) // 日期长度不一致时
}
break
case 'DBT': // 日期范围
if (value[0]) {
// '>='
_hide = !(v >= value[0])
}
if (value[1] && !_hide) {
// '<='
_hide = v ? !(v <= value[1]) : true
if (_hide) {
_hide = !new RegExp('^' + value[1]).test(v)
}
}
break
case 'IS_UNDEF': // ['为空', '不为空']
_hide = value == '为空' ? isDef(v) : !isDef(v)
break
case 'SL': // 'like'
default:
_hide = v ? !new RegExp(value).test(v) : true
break
}
// 没有隐藏(显示的)的 -> 判断是否隐藏
if (!arr[i]._hide && _hide) {
this.$set(arr[i], '_hide', _hide)
}
}
},
注明:本文仅用于学习记录,如有侵权,请联系删除!