更新记录
1.0.0(2026-08-15) 下载此版本
v1.0.0
- 功能特性
- 支持单选/多选模式切换
- 支持面包屑层级导航(基于 dm-breadcrumb)
- 支持搜索过滤(关键字匹配 + 层级展示)
- 支持懒加载(异步加载子节点)
- 支持平级数据源自动转树(parent-field)
- 支持半选状态、半选返回值
- 支持自定义触发器插槽
- 兼容 vue2 / vue3(uni-app 条件编译)
- 组件依赖
- @dcloudio/uni-ui(提供 uni-popup、uni-icons)
- dm-breadcrumb(层级导航)
- 安装说明
- 将 dm-tree 放入 uni_modules/ 后 easycom 自动注册
- 使用 npm 方式时需在 pages.json 配置 easycom 规则
平台兼容性
uni-app(4.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | - | √ | √ | √ | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
dm-tree 树形选择
环境要求 & 前置条件
使用前请确认满足以下条件:
| 项目 | 要求 |
|---|---|
| 框架 | uni-app 工程 |
| Vue 版本 | Vue 2 / Vue 3(组件内部已做兼容处理) |
| 安装方式 | 支持 uni_modules 自动注册 或 npm install 手动引入(二选一) |
| 运行时依赖 | 必须安装 @dcloudio/uni-ui(本组件使用了 uni-popup、uni-icons) |
| 组件依赖 | 必须安装 dm-breadcrumb(npm 方式安装时包名为 @harbymail/dm-breadcrumb;本组件的层级导航使用了面包屑组件) |
| SCSS 支持 | 必须安装 sass 和 sass-loader(组件使用 SCSS + 嵌套 + mixin) |
| 依赖 API | uni.showLoading / uni.hideLoading(uni-app 内置,无需额外安装) |
| 支持平台 | H5、App(Android/iOS)、小程序 |
1. 安装 dm-tree 组件
uni_modules 自动注册(推荐)
将 dm-tree 目录放到项目的 uni_modules/ 下。easycom 会自动扫描并注册,使用时无需 import:
项目根目录/
└── uni_modules/
└── dm-tree/
└── components/dm-tree/
└── dm-tree.vue
2. 安装 uni-ui(运行时依赖)
本组件内部使用了 uni-popup(弹窗)和 uni-icons(图标),这两个组件来自 @dcloudio/uni-ui。
npm install @dcloudio/uni-ui
或使用 HBuilderX 导入方式:在插件市场搜索 uni-ui 通过 导入插件 方式安装。
如果项目本身已经使用了
@dcloudio/uni-ui或uni-ui已存在于uni_modules中,则无需重复安装。
2.1 安装 dm-breadcrumb(组件依赖)
本组件的层级导航使用了 dm-breadcrumb 面包屑组件。
easycom 自动注册(推荐):在 HBuilderX 插件市场搜索 dm-breadcrumb 点击「导入插件」,或直接将 dm-breadcrumb 目录放到项目的 uni_modules/ 下,easycom 自动注册,无需 import。
npm 安装(可选):
npm install @harbymail/dm-breadcrumb
npm 方式需要手动引入组件,且需在 pages.json 的 easycom custom 中配置映射(见下文第 3 节示例中的 ^dm-breadcrumb$ 规则)。
3. 配置 easycom(让 uni-popup、uni-icons 自动注册)
仅当采用方式 A(uni_modules 安装)时需要配置。 采用方式 B(npm 手动引入)时,可在页面中直接
import UniPopup from '@dcloudio/uni-ui/lib/uni-popup/uni-popup.vue'手动注册,跳过此步。
dm-tree 本身在 uni_modules 下走默认 easycom 规则即可自动注册;但 @dcloudio/uni-ui 包内的 uni-popup、uni-icons 路径是扁平结构(uni-popup/uni-popup.vue),不符合 easycom 默认规则(uni_modules/插件ID/components/组件名/组件名.vue),必须配置 easycom custom 规则,否则会报 "Failed to mount component: template or render function not defined" 或 <uni-popup>、<uni-icons> 无法识别。
在 pages.json 顶部添加:
{
"easycom": {
"autoscan": true,
"custom": {
"^dm-breadcrumb$": "dm-breadcrumb/components/dm-breadcrumb/dm-breadcrumb.vue",
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
"pages": [ ... ]
}
4. 安装 SCSS(样式编译依赖)
组件大量使用 SCSS 特性:<style lang="scss" scoped>、BEM 嵌套语法(&--reference、&__checkbox)、@include mixin。不装会导致样式全部失效(弹窗无圆角、flex 布局错乱、checkbox 样式不存在等)。
# 注意:sass-loader 必须用 v10 大版本,更高版本与 uni-app 不兼容
npm install sass sass-loader@10 -D
如果项目只使用 HBuilderX(默认支持 SCSS),则无需手动安装。
5. 配置 Vue 版本(如使用 Vue 3)
在 manifest.json 中指定 Vue 版本:
{
"vueVersion": "3"
}
组件内部通过条件编译 // #ifdef VUE2 / // #ifdef VUE3 自动兼容两种版本的 v-model。
6. 目录结构确认
方式 A(uni_modules 安装):
项目根目录/
├── uni_modules/
│ └── dm-tree/ # 本组件
│ ├── components/dm-tree/
│ │ ├── dm-tree.vue # 入口文件(必须叫 dm-tree.vue)
│ │ ├── tree-main.vue
│ │ ├── tree-node.vue
│ │ └── ...
│ ├── package.json
│ └── README.md
├── pages.json # 配置 easycom 规则
├── manifest.json # 配置 vueVersion
└── package.json # 安装 sass、@dcloudio/uni-ui
重要:入口文件必须命名为
dm-tree.vue(与组件名一致),否则 easycom 默认规则匹配不到。如果文件名不一致,请重命名或自行在 easycom custom 中配置映射规则。
方式 B(npm 安装):
npm install @harbymail/dm-tree @harbymail/dm-breadcrumb @dcloudio/uni-ui
npm install sass sass-loader@10 -D
项目根目录/
├── pages/
├── pages.json # 无需配置 dm-tree 的 easycom
├── manifest.json # 配置 vueVersion
└── package.json # 安装 @harbymail/dm-tree、@harbymail/dm-breadcrumb、@dcloudio/uni-ui、sass
7. 完整配置示例(最小可用)
package.json:
{
"dependencies": {
"@harbymail/dm-tree": "^1.0.0",
"@harbymail/dm-breadcrumb": "^1.0.0",
"@dcloudio/uni-ui": "^1.5.12"
},
"devDependencies": {
"sass": "^1.x",
"sass-loader": "^10.5.2"
}
}
pages.json(顶部,仅方式 A 需要):
{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
"pages": [ ... ]
}
manifest.json:
{
"vueVersion": "3"
}
8. 常见问题排查
| 现象 | 原因 | 解决方案 |
|---|---|---|
| 组件不显示 / 报 "template or render function not defined" | easycom 未配置或配置错误 | 检查 pages.json 的 easycom custom 规则 |
| 弹窗无圆角、布局错乱、checkbox 样式缺失 | SCSS 未安装 | npm install sass sass-loader@10 -D |
<uni-icons> 不显示图标 |
@dcloudio/uni-ui 未安装 |
npm install @dcloudio/uni-ui |
| 修改 easycom 配置后不生效 | easycom 配置改了不会重新编译 | 改动任意页面文件后保存,触发重新编译 |
组件引入报错找不到 tree.vue |
入口文件名不是 dm-tree.vue |
重命名为 dm-tree.vue 或在 easycom custom 中配置 |
| sass-loader 版本过高报错 | sass-loader v11+ 与 uni-app 不兼容 | 锁定 sass-loader@10 |
9. 快速验证
方式 A(uni_modules):
<template>
<!-- easycom 自动注册,无需 import -->
<dm-tree v-model="val" :data="treeData" />
</template>
<script>
export default {
data() {
return {
val: [],
treeData: [
{
label: '总部',
name: '1',
children: [
{ label: '研发部', name: '1-1' },
{ label: '市场部', name: '1-2' }
]
}
]
};
}
};
</script>
方式 B(npm):
<template>
<dm-tree v-model="val" :data="treeData" />
</template>
<script>
import DmTree from '@harbymail/dm-tree';
export default {
components: { DmTree },
data() {
return {
val: [],
treeData: [
{
label: '总部',
name: '1',
children: [
{ label: '研发部', name: '1-1' },
{ label: '市场部', name: '1-2' }
]
}
]
};
}
};
</script>
点击触发器应弹出带圆角、有搜索框、有面包屑导航的树形选择弹窗。
基础用法
<template>
<dm-tree
v-model="checked"
:data="treeData" />
</template>
<script>
export default {
data() {
return {
checked: [],
treeData: [
{
label: '总部',
name: '1',
children: [
{ label: '研发中心', name: '1-1' },
{ label: '市场中心', name: '1-2' }
]
}
]
};
}
};
</script>
单选 / 多选
<!-- 单选,可选任意节点 -->
<dm-tree v-model="val1" :data="treeData" :multiple="false" />
<!-- 单选,只能选叶节点 -->
<dm-tree v-model="val2" :data="treeData" :multiple="false" leaf-only />
<!-- 多选(默认),只能选叶节点 -->
<dm-tree v-model="val3" :data="treeData" leaf-only />
<!-- 多选,可选任意节点 -->
<dm-tree v-model="val4" :data="treeData" />
不可编辑的树
<dm-tree :data="treeData" :show-checkbox="false" />
平级数据结构
传入非树形数组,通过 parent-field 指定父级字段自动构建。
<dm-tree
v-model="vals"
:data="flatData"
parent-field="pid"
text-field="text"
id-field="id"
child-id-field="children" />
懒加载
<dm-tree
v-model="vals"
:data="treeData"
lazy
:load="loadNode" />
methods: {
loadNode(node, resolve) {
// node.level = 0 为根节点
if (node.level === 0) {
resolve([{ label: '区域', name: 'area', leaf: false }]);
} else {
setTimeout(() => {
resolve([{ label: '节点1', name: 'n1', leaf: true }]);
}, 500);
}
}
}
自定义触发器(默认插槽)
<dm-tree v-model="val" :data="treeData">
<view class="my-trigger">
<text>点击选择组织</text>
<text class="arrow">›</text>
</view>
</dm-tree>
自定义面包屑前缀 & 已选列表
<!-- 自定义前缀为"根节点" -->
<dm-tree v-model="val" :data="treeData" breadcrumb-prefix="根节点" />
<!-- 不显示前缀 -->
<dm-tree v-model="val" :data="treeData" breadcrumb-prefix="" />
<!-- 有初始值时自动弹出已选列表 -->
<dm-tree v-model="val" :data="treeData" default-show-checked />
returnType 返回值类型
returnType 控制 v-model 绑定的数据格式,支持四种模式:
"string"(默认)
返回选中节点的 idField 字段值组成的数组,适合只需存储 ID 的场景。
<dm-tree v-model="val" :data="treeData" return-type="string" />
// 假设选中 "前端开发部(name: '1-1-1')" 和 "测试部(name: '1-1-3')"
// val = ['1-1-1', '1-1-3']
"object"
返回选中节点的 原始数据对象组成的数组,适合需要获取完整节点信息的场景。
<dm-tree v-model="val" :data="treeData" return-type="object" />
// 假设选中 "前端开发部" 和 "测试部"
// val = [
// { label: '前端开发部', name: '1-1-1' },
// { label: '测试部', name: '1-1-3' }
// ]
"halfObject"
返回 半选状态(indeterminate)节点的原始数据对象数组。当父节点部分子节点被选中时,父节点为半选状态。配合父子关联模式使用,适合需要获取半选节点完整信息的场景。
<dm-tree v-model="val" :data="treeData" return-type="halfObject" />
// 假设 "研发中心" 下部分子节点被选中,研发中心为半选状态
// val = [
// { label: '研发中心', name: '1-1', children: [...] }
// ]
"halfString"
返回 半选状态(indeterminate)节点的 idField 字段值组成的数组。与 halfObject 类似,但只返回 ID 值。
<dm-tree v-model="val" :data="treeData" return-type="halfString" />
// 假设 "研发中心" 下部分子节点被选中
// val = ['1-1']
四种模式对比
| returnType | 返回值示例 | 适用场景 |
|---|---|---|
string |
['1-1-1', '1-1-3'] |
只需存储 ID,后端反查 |
object |
[{ label: '前端开发部', name: '1-1-1' }, ...] |
需要完整节点数据 |
halfObject |
[{ label: '研发中心', name: '1-1', ... }] |
获取半选节点完整数据 |
halfString |
['1-1'] |
获取半选节点 ID |
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| data | Array | [] |
树形数据源 |
| value / modelValue | Array | — | 选中值,数组形式 |
| title | String | "选择树" |
弹窗标题 |
| textField | String | "label" |
显示文字字段 |
| idField | String | "name" |
标识字段 |
| childIdField | String | "children" |
子节点字段 |
| parentField | String | — | 平级数据时指定父级字段,自动构建树 |
| placeholder | String | "请选择" |
占位文字 |
| showBorder | Boolean | false |
触发器边框 |
| showCheckbox | Boolean | true |
是否显示选择框 |
| multiple | Boolean | true |
多选 / 单选 |
| leafOnly | Boolean | false |
只能选叶节点 |
| lazy | Boolean | false |
懒加载模式 |
| load | Function | — | 懒加载方法,返回子节点数据 |
| clearable | Boolean | true |
显示重置按钮 |
| checkStrictly | Boolean | false |
父子不关联 |
| returnType | String | "string" |
返回值类型:string / object / halfObject / halfString |
| includeHalfChecked | Boolean | false |
是否包含半选节点 |
| seachPlaceholder | String | "请输入关键字查询" |
搜索框占位文字 |
| breadcrumbPrefix | String | title |
面包屑前缀文字,"" 不显示 |
| defaultShowChecked | Boolean | false |
初始有值时自动弹出已选列表 |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
| input / update:modelValue | Array | 选中值变化 |
| search | keyword | 搜索触发 |
| clear | — | 搜索框清空时触发(点击 X 按钮 或 backspace 删除到清空时) |
| reset | — | 重置触发 |
Slots
| 插槽 | 说明 |
|---|---|
| default | 自定义选择框触发器,替换默认 placeholder + text + 箭头 |
数据格式
[
{
label: '总部', // 显示文字 (textField)
name: '1', // 唯一标识 (idField)
children: [ // 子节点 (childIdField)
{ label: '研发部', name: '1-1' },
{ label: '市场部', name: '1-2' }
]
}
]

收藏人数:
下载插件并导入HBuilderX
下载示例项目ZIP
赞赏(0)
下载 10
赞赏 0
下载 12509475
赞赏 1943
赞赏
京公网安备:11010802035340号