Commit 398d1af1 authored by liyan's avatar liyan

11月文章分享

parent 1126438d
Pipeline #17164 failed with stage
---
title: 前端实现elementUI树状表格的模糊搜索、关键字高亮...
date: 2022/11/29 08:42:20
tags:
- 前端
- JavaScript
author: 李燕
---
话说,elementUI的el-table组件在本人的项目中,已经应用很多次了。
但是el-table的树状表格功能,本人这两天才第一次用到。参照文档,按照指定格式赋值data,树状表格很容易就渲染成功了。
但是,接下来的,基于树状表格的延伸功能,就费了一点小心思了,故此记录一下(以下功能实现全部基于Vue2+elementUI项目)。
<!-- more -->
### 一、前端实现树状表格的模糊搜索
**功能要求:**
若父节点有,则该父节点下的所有子节点返回;若父节点没有,但子节点有,则该子节点及以上层级的父节点均需返回。
**实现重点:**
1. 关键字匹配(`name.indexOf(keyWords) > -1`
2. 匹配到的数据重新组装成树形结构(循环、递归)
**方法封装:**
```js
/**
* @param treeData 原始树形数据
* @param inputValue 用户搜索的关键字
* @param key 被匹配的对象(键名)
* @return Array 匹配到的树形数据
*/
filterTree(treeData, inputValue, key) {
let newTreeData = [];
treeData.forEach(item => {
if (item[key].indexOf(inputValue) > -1) {
newTreeData.push(item)
} else {
if (item.children && item.children.length > 0) {
// 父级不匹配,继续向下查询子级是否匹配
const arr = this.filterTree(item.children, inputValue, key);
// 如果子级匹配,将符合条件的子级和父级push到目标数组中
if (arr && arr.length > 0) {
const obj = {
...item,
children: arr
};
newTreeData.push(obj);
}
}
}
});
return newTreeData;
},
```
**延伸:**
若父节点有,仍需继续向下查询子节点是否匹配,而不是子节点全部返回,怎么处理?
将上述if里面的代码改成如下即可。
```js
if (item[key].indexOf(inputValue) > -1) {
// 父级匹配,继续向下查询子级是否匹配
const arr = this.filterTree(item.children, inputValue, key);
const obj = {
...item,
children: arr
};
newTreeData.push(obj)
}
```
### 二、关键字高亮
**功能要求:**
在模糊搜索得到的新树状表格中,将匹配到的关键字高亮。
**实现重点:**
1. 匹配关键字
2. 替换关键字为带有标签的关键字
3. 给标签添加样式
**方法封装:**
```js
hightLightText(text) {
if (text) {
const reg = new RegExp( this.inputValue, 'gi')// 动态正则表达式
return text.replace(reg, `<span style="color: #1F5FB1;">${this.inputValue}</span>`)// 使用replace替换
}
}
```
**页面渲染:**
```js
<template v-slot:name="record">
<span v-html="hightLightText(record.name)"></span>
</template>
```
### 三、动态设置树状表格的展开/折叠
**功能要求:**
树形表格初始状态默认是折叠的,当关键字搜索后,树形表格变为展开状态。
**实现重点:**
官方提供了`default-expand-all`属性控制树形表格的展开折叠,但是只有初始化的时候是生效的,而动态修改是无效的。
所以我们每修改一次,就需要让表格重新渲染一次。
**具体实现:**
```js
<v-table
ref="table"
v-if="refreshTable"
:loading="loading"
:dataSource="dataSource"
:columns="columns"
:defaultExpandAll="defaultExpandAll"
>
</v-table>
doSearch() {
this.refreshTable = false
this.$nextTick(()=> {
this.refreshTable = true
})
this.defaultExpandAll = true
}
```
上述代码中,当搜索事件doSearch执行时,通过变更refreshTable的值,来控制v-table组件(基于el-table二次封装的)的重新渲染。
注意,一定要加上nextTick(),或者延时器,否则,defaultExpandAll的更改会无效。推荐使用nextTick(),因为延时器会造成页面跳动。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment