vue3 el-tree结合el-input实现文字过滤,并且只点击根节点时处理某些逻辑
效果如图:
只点击红色框内容触发对应函数,实现相应逻辑,点击一级二级节点不触发。
直接看代码
<template>
<el-row style="min-height: 100vh">
<el-col class="left" :md="8">
<div class="left-content">
<el-form
label-width="100px"
>
<el-form-item
label="人员名称"
label-width="95px"
>
<div class="filter-input">
<el-input v-model="filterText" clearable placeholder="请输入人员名称"/>
</div>
</el-form-item>
</el-form>
<el-tree
v-if="isShowTree"
ref="treeRef"
:data="userTreeData"
default-expand-all
:filter-node-method="filterNode"
:props="defaultProps"
@node-click="clickNameNode" //点击节点触发
/>
</div>
</el-col>
</template>
<script lang="ts" >
import { getTreeList } from "xxx"
import { ElTree } from 'element-plus'
export default defineComponent({
name: 'UserInfoManagement',,
setup() {
interface Tree {
id: number
label: string
children?: Tree[]
}
const state = reactive({
defaultProps: {
children: 'children', // 渲染的子节点数据
label: 'label', // 用户树名称展示
},
userTreeData: [], // 用户树数据
isShowTree: false, // 是否渲染用户树
})
const filterText = ref('')
const treeRef = ref<InstanceType<typeof ElTree>>()
onMounted(() => {
getTree()
})
onBeforeUnmount(() => {
state.isShowTree = false
})
watch和filterNode实现对用户树的文字过滤
// 监听filterText==>input绑定的值
watch(filterText, (val) => {
treeRef.value!.filter(val)
})
// 过滤节点内容
const filterNode = (value: string, data: Tree) => {
if (!value) return true
return data.label.includes(value)
}
/**
* @description 解析proxy数据为普通数据
* @param value
*/
const analysisProxy = (value: any) => {
return JSON.parse(JSON.stringify(value))
}
// 获取用户树数据
const getTree = async () => {
const { data } = await getTreeList()
if (data && data.length > 0) {
state.userTreeData = data
state.isShowTree = true
}
}
// 点击树节点触发
const clickNameNode = (treeNode: object) => {
const nowNode = analysisProxy(treeNode)
// 点击的是用户(根节点)
// 次处我是和后端商量让后端加个type字段来区分根节点还是父节点
if (nowNode.type === '1') {
xxx
}
// 也可以这么判断
if (!nowNode.children) {
//判断还有没有children属性,一般情况根节点是不应该再返回children属性的
}
}
return {
...toRefs(state),
filterText,
treeRef,
clickNameNode,
filterNode,
}
},
})
</script>
<style lang="scss" scoped>
.left {
padding: 20px;
.left-content{
min-height: 70vh;
.filter-input {
min-height: 30px;
margin: 0px;
min-width: 130px;
}
}
}
</style>