更新记录

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-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' }
    ]
  }
]

隐私、权限声明

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

无

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

插件不采集任何数据

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

无

许可协议

MIT协议