<template>
<div class="person">
<a-input-search v-model="searchStr" placeholder="输入搜选项" style="width:200px;" @search="onSearch"></a-input-search>
<!-- selectedKeys是选中项key的集合,expandedKeys是展开项key的集合 -->
<a-tree
v-model="checkedKeys"
:treeData="treeData"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeys"
@expand="onExpand"
:autoExpandParent="autoExpandParent"
:replaceFields="replaceFields"
@select="onSelect"
@onCheck="onCheck"
>
<template slot='title' slot-scope={name}>
<span v-html="name.replace(new RegExp(searchValue,'g'),'<span style=color:#f50>'+ searchValue +'</span>')"></span>
</template>
</a-tree>
</div>
</template>
<script>
export default {
name: 'Person',
components: {
},
data() {
return {
replaceFields: { title: 'name' },
expandedKeys: [],
backupsExpandedKeys: [],
autoExpandParent: false,
checkedKeys: [],
selectedKeys: [],
searchValue: '',
treeData: [
{
name: '江苏省',
key: '江苏省',
scopedSlots: { title: 'title' },
children: [
{
name: '南京市',
key: '南京市',
scopedSlots: { title: 'title' },
children: [
{
name: '建邺区',
key: '建邺区',
scopedSlots: { title: 'title' },
children: [
{
name: '永初路',
key: '永初路',
scopedSlots: { title: 'title' },
children: [
{ name: '清荷北园', key: '清荷北园', scopedSlots: { title: 'title' } },
{ name: '清荷南园', key: '清荷南园', scopedSlots: { title: 'title' } },
],
},
{
name: '油坊桥路',
key: '油坊桥路',
scopedSlots: { title: 'title' },
children: [
{ name: '莲花北苑', key: '莲花北苑', scopedSlots: { title: 'title' } },
{ name: '经天路苑', key: '经天路苑', scopedSlots: { title: 'title' } },
],
},
{ name: '中和路', key: '中和路', scopedSlots: { title: 'title' } },
],
},
{ name: '雨花台区', key: '雨花台区', scopedSlots: { title: 'title' } },
{ name: '栖霞区', key: '栖霞区', scopedSlots: { title: 'title' } },
],
},
{
name: '0-0-1',
key: '0-0-1',
scopedSlots: { title: 'title' },
children: [
{ name: '0-0-1-0', key: '0-0-1-0', scopedSlots: { title: 'title' } },
{ name: '0-0-1-1', key: '0-0-1-1', scopedSlots: { title: 'title' } },
{ name: '0-0-1-2', key: '0-0-1-2', scopedSlots: { title: 'title' } },
],
},
{
name: '0-0-2',
key: '0-0-2',
scopedSlots: { title: 'title' },
},
],
},
],
searchStr: '',
};
},
methods: {
onSearch() {
this.searchValue = this.searchStr;
if (this.searchValue === '') {
this.expandedKeys = [];
} else {
this.expandedKeys = [];
this.backupsExpandedKeys = [];
const candidateKeysList = this.getkeyList(this.searchValue, this.treeData, []);
candidateKeysList.forEach(
(item) => {
const key = this.getParentKey(item, this.treeData);
// eslint-disable-next-line no-shadow
if (key && !this.backupsExpandedKeys.some((item) => item === key)) this.backupsExpandedKeys.push(key);
},
);
const { length } = this.backupsExpandedKeys;
// eslint-disable-next-line no-plusplus
for (let i = 0; i < length; i++) {
this.getAllParentKey(this.backupsExpandedKeys[i], this.treeData);
}
this.expandedKeys = this.backupsExpandedKeys.slice();
}
},
// 获取节点中含有value的所有key集合
getkeyList(value, tree, keyList) {
// eslint-disable-next-line no-plusplus
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.name.indexOf(value) > -1) {
keyList.push(node.key);
}
if (node.children) {
this.getkeyList(value, node.children, keyList);
}
}
return keyList;
},
// 该递归主要用于获取key的父亲节点的key值
getParentKey(key, tree) {
let parentKey;
let temp;
// eslint-disable-next-line no-plusplus
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some((item) => item.key === key)) {
parentKey = node.key;
// eslint-disable-next-line no-cond-assign
} else if (temp = this.getParentKey(key, node.children)) {
parentKey = temp;
}
}
}
return parentKey;
},
// 获取该节点的所有祖先节点
getAllParentKey(key, tree) {
let parentKey;
if (key) {
parentKey = this.getParentKey(key, tree);
if (parentKey) {
if (!this.backupsExpandedKeys.some((item) => item === parentKey)) {
this.backupsExpandedKeys.push(parentKey);
}
this.getAllParentKey(parentKey, tree);
}
}
},
onExpand(expandedKeys) {
this.expandedKeys = expandedKeys;
this.autoExpandParent = false;
},
onCheck(checkedKeys) {
this.checkedKeys = checkedKeys;
},
onSelect(selectedKeys, info) {
this.selectedKeys = selectedKeys;
},
},
};
</script>
<style scope>
</style>
参考https://blog.csdn.net/py_boy/article/details/103471706的实现方式