Skip to content

LimeTree 树形组件

一个功能丰富的树形组件,用于展示多层次的结构列表。支持节点选择、级联选择、异步加载、搜索过滤等多种配置,可用于组织架构、文件目录、菜单导航等多种场景。组件提供了丰富的自定义选项,可以满足各种复杂的树形结构展示需求。

插件依赖:lime-sharedlime-stylelime-checkboxlime-loading

文档链接

📚 组件详细文档请访问以下站点:

安装方法

  1. 在uni-app插件市场入口 中搜索并导入lime-tree
  2. 导入后可能需要重新编译项目
  3. 在页面中使用l-tree组件
  4. 本插件只支持源码(无法试用和普通授权)

代码演示

基础用法

最简单的树形组件用法,通过data设置树的节点数据。

html
<l-tree 
  :data="data" 
  :default-expanded-keys="defaultExpandedKeys" 
  expand-on-click 
  checkable 
/>
js
// setup 语法
const data = ref([
  {
    label: '道生一',
    key: '1',
    children: [
      {
        label: '一生二',
        key: '1-1',
        children: [
          {
            label: '二生三',
            key: '1-1-1',
            children: [
              { label: '三生万物', key: '1-1-1-1' }
            ]
          }
        ]
      }
    ]
  }
])

const defaultExpandedKeys = ref(['1', '1-1'])

自定义字段名

通过key-fieldlabel-fieldchildren-field自定义节点数据的字段名。

html
<l-tree 
  :data="customData" 
  :default-expanded-keys="defaultExpandedKeys" 
  key-field="id"
  label-field="name" 
  children-field="items" 
  selectable 
/>
js
// setup 语法
const customData = ref([
  {
    name: '道生一',
    id: '1',
    items: [
      {
        name: '一生二',
        id: '1-1',
        items: [
          {
            name: '二生三',
            id: '1-1-1',
            items: [
              { name: '三生万物', id: '1-1-1-1' }
            ]
          }
        ]
      }
    ]
  }
])

const defaultExpandedKeys = ref(['1', '1-1'])

级联选择

设置cascade属性开启级联选择,选中父节点时会自动选中所有子节点。

html
<l-tree 
  :data="data" 
  cascade 
  :default-expanded-keys="defaultExpandedKeys"
  :default-checked-keys="defaultCheckedKeys" 
  @checked="updateCheckedKeys" 
  checkable 
/>
js
// setup 语法
// 树形数据结构
const data = ref([
  {
    label: '道生一',
    key: '1',
    children: [
      {
        label: '一生二',
        key: '1-1',
        children: [
          {
            label: '二生三',
            key: '1-1-1',
            children: [
              { label: '三生万物', key: '1-1-1-1' }
            ]
          }
        ]
      }
    ]
  }
])

const defaultExpandedKeys = ref(['1', '1-1'])
const defaultCheckedKeys = ref(['1-1-1'])

const updateCheckedKeys = (keys: any[]) => {
  console.log('选中的节点:', keys)
}

搜索过滤

通过pattern属性设置搜索关键词,可以过滤树节点。showIrrelevantNodes可以设置只显搜索节点

html
<input 
  type="text" 
  placeholder="输入节点名称"
  v-model="pattern" 
/>

<view style="flex-direction: row; padding: 10px; align-items: center;">
  <switch :checked="showIrrelevantNodes" @change="switchChange"/>
  <text>{{ showIrrelevantNodes ? '显示所有节点' : '隐藏搜索无关的节点' }}</text>
</view>

<l-tree 
  :data="data" 
  expand-on-click 
  :pattern="pattern"
  :show-irrelevant-nodes="showIrrelevantNodes"
/>
js
// setup 语法
const pattern = ref('')
const showIrrelevantNodes = ref(false)

// 树形数据
const data = ref([
  {
    label: '0',
    key: '0',
    children: [
      {
        label: '0-0',
        key: '0-0',
        children: [
          { label: '0-0-0', key: '0-0-0' },
          { label: '0-0-1', key: '0-0-1' }
        ]
      },
      {
        label: '0-1',
        key: '0-1',
        children: [
          { label: '0-1-0', key: '0-1-0' },
          { label: '0-1-1', key: '0-1-1' }
        ]
      }
    ]
  }
])

const switchChange = (event: UniSwitchChangeEvent) => {
  showIrrelevantNodes.value = event.detail.value
}

异步加载

使用 load-node 回调来加载数据。异步加载时,所有 isLeaffalse 并且 children 不为数组的节点会被视为未加载的节点。

html
<l-tree 
  :data="asyncData" 
  :load-node="handleLoad"
  :expanded-keys="expandedKeys"
  @expanded="handleExpandedKeysChange" 
  checkable 
/>
js
// setup 语法
const asyncData = ref([
  {
    label: '道生一',
    key: '1',
    isLeaf: false
  },
  {
    label: '一生二',
    key: '2',
    isLeaf: false
  }
])

const expandedKeys = ref([])

const handleLoad = (node: UTSJSONObject): Promise<boolean> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      // 模拟异步加载数据
      node.children = [
        {
          label: node.label === '道生一' ? '一生二' : '二生三',
          key: `${node.key}-1`,
          isLeaf: false
        }
      ]
      resolve(true)
    }, 1000)
  })
}

const handleExpandedKeysChange = (keys: string[]) => {
  expandedKeys.value = keys
}

自定义节点内容

通过插槽自定义节点的展开/收缩图标和内容。

html
<l-tree 
  :data="data"  
  checkbox-placement="right"
  expand-on-click 
  center
  checked-color="red"
  @click="onClick"
  checkable 
>
  <template #switcher="{expanded}">
    <text v-show="expanded">🤔</text>
    <text v-show="!expanded">🐱</text>
  </template>
  <template #content="{node}">
    <view style="flex-direction: row; align-items: center;">
      <image style="width: 30px; height: 30px;" src="/static/logo.png"></image>
      <text style="padding: 10px;">{{node.label}}公司</text>
    </view>
  </template>
</l-tree>
js
// setup 语法
function repeat(count : number, value ?: string|number) : string|number[] {
	const result : string|number[] = [];
	for (let i = 0; i < count; i++) {
		result.push(value ?? '');
	}
	return result;
}
function createLabel(level : number) : string {
	if (level == 4)
		return '道生一'
	if (level == 3)
		return '一生二'
	if (level == 2)
		return '二生三'
	if (level == 1)
		return '三生万物'
	return ''
}

function createData(level = 4, baseKey : string = '') : UTSJSONObject[] | null {
	if (level == 0) return null
	return repeat(6 - level, null).map((_, index) : UTSJSONObject => {
		const key = `${baseKey}${level}${index}`
		return {
			label: createLabel(level),
			key,
			children: createData(level - 1, key)
		}
	})
}

const data = ref(createData())

const onClick = (node: UTSJSONObject, siblings: UTSJSONObject[]) => {
	// 获取当前节点所在兄弟节点的下标,可以做增删等操作
	const index = siblings.findIndex((item) => item['key'] == node['key'])
	console.log('index', index)
	// 删除
	// siblings.splice(0, 1)
	
}

快速预览

导入插件后,可以直接使用以下标签查看演示效果:

html
<!-- 代码位于 uni_modules/lime-tree/components/lime-tree -->
<lime-tree />

插件标签说明

标签名说明
l-tree组件标签
lime-tree演示标签

Vue2使用说明

main.js中添加以下代码:

js
// vue2项目中使用
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)

详细配置请参考官方文档:Vue Composition API

API文档

Props 属性说明

参数说明类型默认值
cascade是否关联选项booleanfalse
checkStrategy设置勾选策略来指定勾选回调返回的值,all 表示回调函数值为全部选中节点;parent 表示回调函数值为父节点(当父节点下所有子节点都选中时);child 表示回调函数值为子节点stringall
checkable是否显示选择框booleanfalse
checkboxPlacement复选框的位置, 可选值:'left' 'right'stringleft
childrenField替代 TreeOption 中的 children 字段名stringchildren
keyField替代 TreeOption 中的 key 字段名stringkey
labelField替代 TreeOption 中的 label 字段名stringlabel
disabledField替代 TreeOption 中的 disabled 字段名stringdisabled
checkedKeys受控的选中多选项string | number-
data树节点数据Object[]-
defaultCheckedKeys默认选中多选项(string | number)[]-
defaultExpandedKeys默认展开项(string | number)[]-
expandedKeys受控的展开项(string | number)[]-
expandOnClick允许点击节点展开/收缩booleanfalse
checkOnClick允许点击节点勾选booleanfalse
loadNode异步加载回调(node: Object) => Promise<boolean>``
pattern搜索内容string``
showIrrelevantNodes搜索时显示无关节点booleantrue
allowCheckingNotLoaded允许勾选未加载节点booleanfalse
indentWidth缩进宽度number24
center节点内容垂直居中booleanfalse
loadingColorloading颜色string-
checkedColorcheckebox选中颜色string-
rotatableSwitchercheckebox选中颜色booleanfalse
highlightBgColor搜到时搜索到的项背景颜色string-
selectedBgColor选择中时背景颜色,默认透明,用于没有勾选框的情况下string-

Events 事件

事件名说明回调参数
update:checked-keys勾选触发_(keys: string
checked勾选触发_(keys: string
update:expanded-keys展开触发_(keys: string
expanded展开触发_(keys: string
click点击触发(node: object, siblings: object[])

Slots 插槽

名称说明参数
switcher展开/收缩图标插槽{ hide: boolean, loading: boolean, expanded: boolean }
content节点内容插槽{ node: Object }

主题定制

组件提供了以下CSS变量,可用于自定义样式:

变量名称默认值描述
--l-tree-node-wrapper-padding-x0节点水平内边距
--l-tree-node-wrapper-padding-y$spacer-tn节点垂直内边距
--l-tree-node-content-height24px节点内容高度
--l-tree-node-line-height1.5节点行高
--l-tree-node-text-color$text-color-1节点文字颜色
--l-tree-arrow-color$gray-6箭头颜色
--l-tree-highlight-bg-color$primary-color-1高亮背景色
--l-tree-font-size$font-size-md字体大小
--l-tree-arrow-size5px箭头尺寸
--l-tree-beziercubic-bezier(0.4, 0, 0.2, 1)动画曲线

支持与赞赏

如果你觉得本插件解决了你的问题,可以考虑支持作者:

支付宝赞助微信赞助

源代码

组件源码