news 2026/6/10 23:05:46

el-tree 二次封装 含搜索

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
el-tree 二次封装 含搜索

<template>
<div class="smart-tree-radio">
<el-input
v-model="keyword"
clearable
placeholder="请输入关键字搜索"
class="smart-tree-radio__search"
/>

<el-tree
ref="treeRef"
:data="filterTreeData"
:props="treeProps"
node-key="value"
default-expand-all
:expand-on-click-node="false"
>
<template #default="{ data }">
<el-radio
class="smart-tree-radio__radio"
:model-value="innerValue"
:value="data.value"
:disabled="data.disabled"
@change="handleRadioChange(data)"
>
{{ data.label }}
</el-radio>
</template>
</el-tree>

<div class="smart-tree-radio__footer">
<el-button size="small" @click="handleClear">清空</el-button>
</div>
</div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { ElTree } from 'element-plus'

interface TreeItem {
label: string
value: string | number
disabled?: boolean
children?: TreeItem[]
}

const props = withDefaults(
defineProps<{
modelValue?: string | number | null
data: TreeItem[]
}>(),
{
modelValue: null,
data: () => []
}
)

const emit = defineEmits<{
'update:modelValue': [value: string | number | null]
change: [node: TreeItem | null]
}>()

const treeRef = ref<InstanceType<typeof ElTree>>()

const keyword = ref('')
const innerValue = ref<string | number | null>(props.modelValue)

const treeProps = {
label: 'label',
children: 'children'
}

/**
* 搜索核心:
* 命中当前节点,保留当前节点;
* 命中子节点,也保留父级路径。
*/
const filterTreeData = computed(() => {
const key = keyword.value.trim()

if (!key) return props.data

const loop = (list: TreeItem[]): TreeItem[] => {
return list.reduce<TreeItem[]>((result, item) => {
const children = item.children ? loop(item.children) : []
const selfMatched = item.label.includes(key)

if (selfMatched || children.length) {
result.push({
...item,
children
})
}

return result
}, [])
}

return loop(props.data)
})

/**
* 外部传 value 后,支持反显。
*/
watch(
() => props.modelValue,
value => {
innerValue.value = value ?? null
},
{
immediate: true
}
)

/**
* el-radio 单选:
* 只改变当前节点 value;
* 不影响父级,不影响子级。
*/
const handleRadioChange = (data: TreeItem) => {
if (data.disabled) return

innerValue.value = data.value

emit('update:modelValue', data.value)
emit('change', data)
}

/**
* 清空:
* 清空当前选中 value。
*/
const handleClear = () => {
innerValue.value = null

emit('update:modelValue', null)
emit('change', null)
}
</script>

<style scoped lang="scss">
.smart-tree-radio {
width: 100%;

&__search {
margin-bottom: 8px;
}

&__radio {
width: 100%;
height: 26px;
display: flex;
align-items: center;
}

&__footer {
margin-top: 8px;
text-align: right;
}
}
</style>

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 21:28:05

[鸿蒙PC命令行移植适配]移植rust三方库ouch到鸿蒙PC的完整实践

欢迎加入【开源鸿蒙PC社区】&#xff0c;一起共建鸿蒙化C/C三方库生态。 前言 ouch 是由 ouch-org 团队开发的压缩与解压缩命令行工具&#xff0c;全称 Obvious Unified Compression Helper&#xff08;直观的统一压缩助手&#xff09;。它旨在提供一种简单、统一的方式来处理…

作者头像 李华
网站建设 2026/6/6 21:26:56

矩阵:从线性代数基础到现代应用

1. 引言&#xff1a;什么是矩阵&#xff1f; 矩阵是数学中一个极其重要的概念&#xff0c;尤其在线性代数领域扮演着核心角色。简单来说&#xff0c;矩阵是一个按照矩形阵列排列的数字、符号或表达式的集合。它不仅是数学理论研究的对象&#xff0c;更是连接代数、几何、物理、…

作者头像 李华
网站建设 2026/6/9 0:29:46

2026上海装修公司推荐:8家靠谱品牌横评,从性价比到智能住宅怎么选?

在上海&#xff0c;装修一套房平均要对接12个供应商、做出200多个决策、承受3到6个月的工期焦虑——这还不算那些入住后才发现的隐蔽工程隐患。据中国建筑装饰协会2025年发布的《家装消费洞察报告》&#xff0c;上海存量房装修占比已攀升至81.3%&#xff0c;而用户最关心的五个…

作者头像 李华