更新记录

1.0.0(2026-08-15) 下载此版本

v1.0.0

  1. 功能特性
    • 支持单选/多选模式切换
    • 支持面包屑层级导航(基于 dm-breadcrumb)
    • 支持搜索过滤(关键字匹配 + 层级展示)
    • 支持懒加载(异步加载子节点)
    • 支持平级数据源自动转树(parent-field)
    • 支持半选状态、半选返回值
    • 支持自定义触发器插槽
    • 兼容 vue2 / vue3(uni-app 条件编译)
  2. 组件依赖
    • @dcloudio/uni-ui(提供 uni-popup、uni-icons)
    • dm-breadcrumb(层级导航)
  3. 安装说明
    • 将 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-popupuni-icons
组件依赖 必须安装 dm-breadcrumb(npm 方式安装时包名为 @harbymail/dm-breadcrumb;本组件的层级导航使用了面包屑组件)
SCSS 支持 必须安装 sasssass-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-uiuni-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-popupuni-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-popupuni-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' }
    ]
  }
]

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议