第一种(直接展开并高亮关键字)
效果图这样的,会把所有的有这些关键字的节点都展开
代码:
这里的逻辑就是通过递归循环把所有和关键字匹配的节点筛选出来
然后通过setCheckedKeys方法把他展开选中
然后通过filterReal把关键字高亮标蓝
javascript
<body>
<div id="app" style="padding:10px;">
<!-- 查询框 -->
<input class="el-textarea__inner" v-model.lazy="title" placeholder="请输入菜单名称"
style="margin-left:10px;width: 220px;" @keyup.enter="getlists"></input>
<!-- 树形菜单 -->
<el-tree :data="data2" node-key="id" :props="defaultProps"
:highlight-current="gaoliang" :default-expanded-keys="openkeys" :default-expand-all="closed"
:show-checkbox='show_checkboxd' ref="tree2">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span v-html="$options.filters.filterReal(node.label, title)"></span>
</span>
</el-tree>
</div>
</body>
<script type="text/javascript">
let v = new Vue({
el: '#app',
filters: {
filterReal(value, key) {
const ind = value.indexOf(key);
if (value.includes(key))
return (
value
.split("")
.slice(0, ind)
.join("") +
'<span class="key-word">' +
key +
"</span>" +
value
.split("")
.slice(ind + key.length)
.join("")
);
return `<span>${value}</span`;
},
},
data() {
return {
data2: [],//列表
defaultProps: {
children: 'children',
label: 'title'
},
title: '',//查询
openkeys:[]
}
},
methods: {
getlists() {
// this.$refs.tree2.filter(this.title);
// return
let that = this
if (that.title != '') {
that.openkeys = []
that.$refs.tree2.setCheckedKeys(that.openkeys);//清空节点选择,节点收起
let arr = []
that.openkeys = this.getAllId(arr, this.data2) //递归拿到查询的所有关键字节点id
that.$refs.tree2.setCheckedKeys(that.openkeys)//根据这些id展开节点
}
},
// 递归:查询tree
getAllId(keys, dataList) {
let that=this
if (dataList && dataList.length) {
for (let i = 0; i < dataList.length; i++) {
if(dataList[i].title.includes(that.title)){
keys.push(dataList[i].id) //查询关键字相同的id添加进去
}
if (dataList[i].children) {
keys = this.getAllId(keys, dataList[i].children)
}
}
}
return keys
},
}
})
</script>
<style scoped>
</style>
</html>
第二种(过滤之后再关键字高亮)
这个是用的官方文档的那个过滤方式,可以参考官方文档看一下。
只不过高亮关键字用这里的
核心写法和上面一样,变动的只有两个地方
1,在tree标签上加上这句话:filter-node-method="filterNode"这个方法复制下面的,
只需要把data.title修改成你字段的名字就行,比如你的字段叫name就是data.name。
如果是lable就是data.lable。其他的不用动
2,差的时候调用这个this.$refs.tree2.filter(this.title);里面的title就是你搜索的值
javascript
<body>
<div id="app" style="padding:10px;">
<!-- 查询框 -->
<input class="el-textarea__inner" v-model.lazy="title" placeholder="请输入菜单名称"
style="margin-left:10px;width: 220px;" @keyup.enter="getlists"></input>
<!-- 树形菜单 -->
<el-tree :data="data2" node-key="id" :props="defaultProps"
:highlight-current="gaoliang" :default-expanded-keys="openkeys" :default-expand-all="closed"
:show-checkbox='show_checkboxd' ref="tree2" :filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span v-html="$options.filters.filterReal(node.label, title)"></span>
</span>
</el-tree>
</div>
</body>
<script type="text/javascript">
let v = new Vue({
el: '#app',
filters: {
filterReal(value, key) {
const ind = value.indexOf(key);
if (value.includes(key))
return (
value
.split("")
.slice(0, ind)
.join("") +
'<span class="key-word">' +
key +
"</span>" +
value
.split("")
.slice(ind + key.length)
.join("")
);
return `<span>${value}</span`;
},
},
data() {
return {
data2: [],//列表
defaultProps: {
children: 'children',
label: 'title'
},
title: '',//查询
openkeys:[]
}
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.title.indexOf(value) !== -1;
},
getlists() {
this.$refs.tree2.filter(this.title);
},
}
})
</script>