Function is introduced
The El-Tree component to be optimized in this section has the following functions:
- All children are displayed after the search
- Nodes match to keyword highlighting
- Remove the background color after the node is out of focus
Implementation approach
- Change the search logic by customalizing filter-node-method
- Highlighting is displayed by adding the class name
- Background color removal is solved by pseudo-class, making highlighted styles take precedence over focus, and setting the background color of clustered nodes to white
The Dom part
<el-tree
ref="tree"
:data="data"
:props="props"
:filter-node-method="filterNodeMethod"
:highlight-current="true"
node-key="value"
:current-node-key="currentNodeKey"
@node-click="handleNodeClick"
>
<template #default="scope">
<div
:class="
keyword === ''
? ''
: scope.data.label.indexOf(keyword) !== -1
? 'has-key-word-style'
: ''
"
>
{{ scope.data.label }}
</div>
</template>
</el-tree>
Copy the code
Js part
FilterNodeMethod (value, data, node) {if (! Value) {return true} return this.getHasKeyword(value, node)}, node) { if (node.data instanceof Array) { node.data = node.data.length > 0 ? node.data[0] : {} } if (node.data.label && node.data.label.indexOf(value) ! == -1) { return true } else { return node.parent && this.getHasKeyword(value, node.parent) } }Copy the code
Style part
El-tree --highlight-current. El-tree-node. is-current >. El-tree-node__content {background-color: #edf6ff! important; } // Hover >. El-tree-node :hover >. El-tree-node__content {background: #f5f7fa! important; El-tree-node :focus >. El-tree-node__content {background: # FFFFFF; }Copy the code
The complete code
<template> <div class="organization-tree"> <span class="tree-title">{{ title }}</span> <div class="tree-list"> <div class="tree-filter"> <el-input v-model="keyword" :placeholder="placeholder" @input="handleInput" /> <el-button v-if="isCreate" icon="el-icon-plus" /> </div> <div class="tree-all" :class="! activeNode ? 'tree-all-iscurrent' : </div> <div class="tree-content"> <el-tree ref="tree" :data="data" :props="props" :filter-node-method="filterNodeMethod" :highlight-current="true" node-key="value" :current-node-key="currentNodeKey" @node-click="handleNodeClick" > <template #default="scope"> <div :class=" keyword === '' ? '' : scope.data.label.indexOf(keyword) ! = = 1? 'has-key-word-style' : '' " > {{ scope.data.label }} </div> </template> </el-tree> </div> </div> </div> </template> <script> export default { name: 'OrganizationTree', props: { isCreate: { type: Boolean, default: true }, title: { type: String, default: 'orgtree'}, data: {type: Array, default: () => []}, props: {type: Object, default: () => ({})}, placeholder: {type: Array, default: () => ({})} String, default: 'Please input keyword'}}, data () {return {keyword: ", currentNodeKey: null, filterData: [], // Filter data activeNode: null // default activation all}}, methods: { async handleInput (v) { this.$refs.tree.filter(v) }, clickAll () { this.activeNode = null this.currentNodeKey = null this.$nextTick(() => { this.$refs.tree.setCurrentKey(null) }) this.$emit('all-click') }, handleNodeClick (data, Node) {if (this.activenode === data.value) {// Click this.clickAll() return} this.activenode = data.value this.$emit('node-click', data, node) }, filterNodeMethod (value, data, node) { if (! value) { return true } return this.getHasKeyword(value, node) }, getHasKeyword (value, node) { if (node.data instanceof Array) { node.data = node.data.length > 0 ? node.data[0] : {} } if (node.data.label && node.data.label.indexOf(value) ! == -1) { return true } else { return node.parent && this.getHasKeyword(value, node.parent) } } } } </script> <style lang="scss"> .organization-tree { background: #ffffff; width: 264px; border-radius: 2px; .tree-title { display: inline-block; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC, serif; font-weight: 400; color: #666666; box-sizing: border-box; padding: 16px 24px; } .tree-list { border-top: 1px solid #e9e9e9; box-sizing: border-box; padding: 16px 24px; .tree-filter { display: flex; margin-bottom: 24px; .el-input__inner { height: 36px; background: #ffffff; border-radius: 2px; border: 1px solid #d9d9d9; } .el-button { width: 32px; height: 36px; background: #ffffff; border-radius: 2px; border: 1px solid #d9d9d9; padding: 0 5px; margin-left: 10px; } } .tree-all { cursor: pointer; color: #666666; height: 26px; line-height: 26px; &-iscurrent { background-color: #edf6ff ! important; } } .tree-all:hover { background-color: #f5f7fa; } .tree-content { height: 500px; overflow: auto; } .has-key-word-style { background-color: #d5ebfc; } } .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content { background-color: #edf6ff ! important; } .el-tree-node:hover > .el-tree-node__content { background: #f5f7fa ! important; } .el-tree-node:focus > .el-tree-node__content { background: #ffffff; } } </style>Copy the code