我们在日常开发中经常会用到筛选的功能,比如一个表格数据,需要根据其中的某一列去进行模糊匹配筛选,一般都是去判断字符串中是否包含某个子字符串,但是这样是不支持首字母模糊匹配的,所以我们可以使用一个第三方包pinyin去实现这种功能。
pinyin可以直接使用npm下载。
1.表格的筛选
js
export function searchedFilter(rows, searchValue, keyValue) {
searchValue = searchValue.trim();
if (searchValue) {
const pathen = /^[\u4e00-\u9fa5]+$/;
if (pathen.test(searchValue)) {
return rows.filter((data) => {
return Object.keys(data).some((key) => {
if (key === keyValue) {
return data[key].includes(searchValue);
}
});
});
} else {
const searchValuePinyin = pinyin(searchValue, {
style: pinyin.STYLE_FIRST_LETTER,
}).join("");
return rows.filter((data) => {
return Object.keys(data).some((key) => {
if (key === keyValue) {
const dataPyArr = pinyin(data[key], {
style: pinyin.STYLE_FIRST_LETTER,
});
const dataPy = dataPyArr.join("");
return dataPy.includes(searchValuePinyin);
}
});
});
}
}
return rows;
}
该方法接收三个参数,rows是表格数据,searchValue是筛选字符串,keyValue是要匹配的表格的某一列的prop。
下面举个例子:
html
<template>
<div class="screen-view">
<span>筛选字段:</span>
<el-input v-model="filterText" style="width:120px"></el-input>
<el-button @click="filterHandle" type="primary">筛选</el-button>
<el-table :data="showTableData" stripe border height="500" :cell-style="{ textAlign: 'center' }"
:header-cell-style="{ textAlign: 'center' }">
<el-table-column label="姓名" prop="name"></el-table-column>
<el-table-column label="地址" prop="address"></el-table-column>
<el-table-column label="职位" prop="job"></el-table-column>
</el-table>
</div>
</template>
<script>
import { searchedFilter } from '@/utils/changePinyin'
export default {
data() {
return {
tableData: [
{ name: '月亮', address: '江苏省南京市', job: '前端开发' },
{ name: '月亮1', address: '江苏省南京市', job: '前端开发' },
{ name: '月亮2', address: '江苏省南京市', job: '前端开发' },
{ name: '大傻', address: '安徽省合肥市', job: '后端开发' },
{ name: '大傻1', address: '安徽省合肥市', job: '后端开发' },
{ name: '大傻2', address: '安徽省合肥市', job: '后端开发' },
{ name: '二狗', address: '四川省成都市', job: '前端开发' },
{ name: '二狗1', address: '四川省成都市', job: '前端开发' },
{ name: '二狗2', address: '四川省成都市', job: '前端开发' },
{ name: '三驴子', address: '河南省郑州市', job: '后端开发' },
{ name: '三驴子1', address: '河南省郑州市', job: '后端开发' },
{ name: '三驴子2', address: '河南省郑州市', job: '后端开发' },
],
showTableData: [],
filterText: ''
}
},
created() {
this.showTableData = this.tableData
},
methods: {
filterHandle() {
this.showTableData = searchedFilter(this.tableData, this.filterText, 'name')
// 这就是筛选表格的姓名字段,如果想筛选别的就把name换成对应的prop
// 支持首字母匹配
}
}
}
</script>
<style lang="scss" scoped>
.screen-view {
height: 100%;
padding: 10px;
box-sizing: border-box;
}
</style>
这个方法只能根据表格的一列进行筛选,如果想同时匹配多列的话,可以使用下面的方法。
js
export function searchedFilters(rows, searchValue, keyValues) {
searchValue = searchValue.trim();
if (searchValue) {
const pathen = /^[\u4e00-\u9fa5]+$/;
if (pathen.test(searchValue)) {
return rows.filter((data) => {
return Object.keys(data).some((key) => {
return keyValues.some((k) => {
if (key === k) {
return data[key].includes(searchValue);
}
});
});
});
} else {
const searchValuePinyin = pinyin(searchValue, {
style: pinyin.STYLE_FIRST_LETTER,
}).join("");
return rows.filter((data) => {
return Object.keys(data).some((key) => {
return keyValues.some((k) => {
if (key === k) {
const dataPyArr = pinyin(data[key], {
style: pinyin.STYLE_FIRST_LETTER,
});
const dataPy = dataPyArr.join("");
return dataPy.includes(searchValuePinyin);
}
});
});
});
}
}
return rows;
}
还是接收三个参数,前面两个跟第一个方法一样,表格数据和筛选字符串,第三个是一个数组,里面存放的是你想匹配的列。
比如我们想同时筛选姓名和地址这两列:
js
filterHandle() {
this.showTableData = searchedFilters(this.tableData, this.filterText, ['name', 'address'])
}
2.树结构的筛选
js
export function treeFilterPY(data, searchValue, keyValue) {
searchValue = searchValue.trim();
if (!searchValue) return true;
const pathen = /^[\u4e00-\u9fa5]+$/;
if (pathen.test(searchValue)) {
return data[keyValue].indexOf(searchValue) !== -1;
}
// 匹配小写
const labelValue = pinyin(data[keyValue], {
style: pinyin.STYLE_FIRST_LETTER,
}).join("");
const searchValuePinyin = pinyin(searchValue, {
style: pinyin.STYLE_FIRST_LETTER,
}).join("");
return labelValue.indexOf(searchValuePinyin) !== -1;
}
这个方法接收三个参数,分别是树结构数据,筛选字符串,对应的prop。
html
<template>
<div class="screen-view">
<span>筛选字段:</span>
<el-input v-model="filterText" style="width:120px"></el-input>
<el-button @click="filterHandle" type="primary">筛选</el-button>
<el-tree ref="treeRef" :data="treeData" :filter-node-method="filterNode"></el-tree>
</div>
</template>
<script>
import { treeFilterPY } from '@/utils/changePinyin'
export default {
data() {
return {
defaultProps: {
children: "children",
label: "label",
},
treeData: [
{
label: '全部',
id: -1,
children: [
{
label: '月亮',
id: 1
},
{
label: '大傻',
id: 2
},
{
label: '二狗',
id: 3
},
{
label: '三驴子',
id: 4
},
]
}
],
filterText: ''
}
},
created() {
this.showTableData = this.tableData
},
methods: {
filterHandle() {
this.$refs.treeRef.filter(this.filterText);
},
filterNode(value, data) {
return treeFilterPY(data, value, this.defaultProps.label);
},
}
}
</script>
<style lang="scss" scoped>
.screen-view {
height: 100%;
padding: 10px;
box-sizing: border-box;
}
</style>