可以使用 node中 style屬性
填寫 display: none 就可以隱藏其他節點 只保留查詢的節點
再通過遞歸 讓每一個節點都能遍歷到
核心代碼:
const setStyleDisplay = (key, nodes) => {
let nums = 0
for (let data of nodes) {
let bl = false
if (data.key.indexOf(key) > -1) {
bl = true
nums += 1
}
if (!!data.children) {
if (data.children.length > 0) {
let count = setStyleDisplay(key, data.children)
if (!bl && count == 0) {
bl = false
} else {
bl = true
}
}
}
if (bl) {
delete data['style']
} else {
data['style'] = 'display: none'
}
}
return nums
}
結果圖:
搜索:
完整代碼 基本的框架是摘抄自antdv的官網 原地址: andtv 樹形控件 可搜索
<template>
<div>
<a-input-search style="margin-bottom: 8px" placeholder="Search" @change="onChange" />
<a-tree
:expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
@expand="onExpand"
>
<template slot="title" slot-scope="{ title }">
<span v-if="title.indexOf(searchValue) > -1">
{{ title.substr(0, title.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ title }}</span>
</template>
</a-tree>
</div>
</template>
<script>
const x = 3
const y = 2
const z = 1
const gData = []
const generateData = (_level, _preKey, _tns) => {
const preKey = _preKey || '0'
const tns = _tns || gData
const children = []
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`
tns.push({ title: key, key, scopedSlots: { title: 'title' } })
if (i < y) {
children.push(key)
}
}
if (_level < 0) {
return tns
}
const level = _level - 1
children.forEach((key, index) => {
tns[index].children = []
return generateData(level, key, tns[index].children)
})
}
generateData(z)
const dataList = []
const generateList = (data) => {
for (let i = 0; i < data.length; i++) {
const node = data[i]
const key = node.key
dataList.push({ key, title: key })
if (node.children) {
generateList(node.children)
}
}
}
generateList(gData)
const getParentKey = (key, tree) => {
let parentKey
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
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children)
}
}
}
return parentKey
}
const setStyleDisplay = (key, nodes) => {
let nums = 0
for (let data of nodes) {
let bl = false
if (data.key.indexOf(key) > -1) {
bl = true
nums += 1
}
if (!!data.children) {
if (data.children.length > 0) {
let count = setStyleDisplay(key, data.children)
if (!bl && count == 0) {
bl = false
} else {
bl = true
}
}
}
if (bl) {
delete data['style']
} else {
data['style'] = 'display: none'
}
}
return nums
}
export default {
data() {
return {
expandedKeys: [],
searchValue: '',
autoExpandParent: true,
gData,
}
},
methods: {
onExpand(expandedKeys) {
this.expandedKeys = expandedKeys
this.autoExpandParent = false
},
onChange(e) {
const value = e.target.value
const expandedKeys = dataList
.map((item) => {
if (item.title.indexOf(value) > -1) {
return getParentKey(item.key, gData)
}
return null
})
.filter((item, i, self) => item && self.indexOf(item) === i)
// 隱藏 不需要的選項
setStyleDisplay(value, gData)
Object.assign(this, {
expandedKeys,
searchValue: value,
autoExpandParent: true,
})
},
},
}
</script>