使用vbenadmin这个框架,最近遇到一个问题,框架中的树结构搜索,是封装好的,搜索到父级的时候搜索就会变成单个,看不到具体的树结构展示,现需要改成自定义搜索,通过关键词定位,保留树结构展示。 过滤选中数据展示在右边,过滤时,现在某个子节点,显示子节点,全部选中子节点,则显示它的父级。
直接上代码
<template>
<div>
<a-input-search
class="search-box"
v-model:value="searchValue"
style="margin-bottom: 8px"
placeholder="搜索"
@change="changeEnter"
/>
</template>
<Row >
<Col :span="12" style="height: 100%">
<BasicTree
:treeData="treeData"
:checkable="true"
ref="treeRef"
@change="change"
:checkStrictly="checkStrictlyValue"
:expandedKeys="expandedKeys"
:auto-expand-parent="autoExpandParent"
:replaceFields="{ key: 'dictKid', title: 'name' }"
>
<template #title="{ name, id }">
<span :id="'item_' + id" v-if="name.indexOf(searchValue) > -1">
{{ name.substr(0, name.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ name.substr(name.indexOf(searchValue) + searchValue.length) }}
</span>
<span :id="'item_' + id" v-else>{{ name }}</span>
</template>
</BasicTree>
</Col>
<Col :span="12" style="margin-top: 30px; padding-left: 30px">
<div class="title">选中的经营范围:</div>
<div v-for="(item, index) in listFilter" :key="index">
<item class="name">{{ item.name }}</item>
</div>
</Col>
</Row>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed, unref, inject, nextTick } from 'vue';
import { BasicTree, TreeItem, TreeActionType } from '/@/components/Tree/index';
import { Col, Row } from 'ant-design-vue';
import { getDictItem, callSaveB } from '/@/api/op/qi/supQuality';
export default defineComponent({
name: ”tree“,
components: { BasicTree, Row, Col },
setup(_, { emit }) {
const treeData = ref<TreeItem[]>([]);
const listFilter: any = ref([]);
const checkStrictlyValue = ref(false);
const searchValue = ref<string>('');
const expandedKeys = ref<string[]>([]);
const autoExpandParent = ref<boolean>(false);
// 获取树数据
async function fetch() {
await getDictItem().then((res) => {
treeData.value = res;
toListData(treeData.value);
});
}
const listData: Array<any> = [];
function toListData(dataList) {
if (dataList && dataList.length > 0) {
for (let d of dataList) {
listData.push(d);
if (d.children) {
toListData(d.children);
}
}
}
}
//搜索过滤定位
function changeEnter() {
const expanded = listData
.map((item: TreeItem) => {
if ((item.name as string).indexOf(searchValue.value) > -1) {
return getParentKey(item.dictKid, treeData.value);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
expandedKeys.value = expanded as string[];
console.log(expandedKeys.value, 'expandedKeys.value');
getTree().setExpandedKeys(expandedKeys.value);
autoExpandParent.value = true;
nextTick(() => {
const keys = expandedKeys.value;
if (keys && keys.length > 0) {
const id = 'item_' + keys[0];
setTimeout(() => {
document.getElementById(id)?.scrollIntoView();
}, 100);
}
});
}
const getParentKey = (key: string, tree: TreeItem[]): string | number | undefined => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some((item) => item.dictKid === key)) {
parentKey = node.dictKid;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
//定义
const treeRef = ref<Nullable<TreeActionType>>(null);
function getTree() {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
}
//选中改变
async function change() {
const checkedKeys: any = getTree().getCheckedKeys();
const checked = checkedKeys.checked ? checkedKeys.checked : checkedKeys;
checkedFilter(checked);
}//选中过滤
function checkedFilter(checked) {
const list: any = ref([]);
treeData?.value.forEach((item) => {
if (checked.includes(item.id)) {
list.value.push(item);
} else {
item.children?.forEach((c) => {
if (checked.includes(c.id)) {
list.value.push(c);
} else {
c.children?.forEach((child) => {
if (checked.includes(child.id)) {
list.value.push(child);
}
});
}
});
}
});
const sort = list.value.sort(compare('orderNo'));
listFilter.value = sort;
}
function compare(p) {
return function (a, b) {
const val1 = a[p];
const val2 = b[p];
return val1 - val2;
};
}
return {
treeRef,
treeData,
change,
listFilter,
checkStrictlyValue,
searchValue,
changeEnter,
expandedKeys,
autoExpandParent,
};
},
});
</script>
<style scoped lang="less">
:deep .ant-tree-checkbox-inner {
border: 1px solid #000 !important;
}
:deep .tree-basic-drawer .ant-drawer-body .scrollbar__wrap {
padding: 0 !important;
}
:deep .justify-end {
justify-content: flex-start !important;
}
.title {
font-size: 15px;
}
.name {
margin: 10px;
font-size: 13px;
}
.search-box{
position: fixed;
z-index: 10;
top: 48px;
width: 400px;
}
</style>