更新记录
0.0.1(2025-02-06)
- init
平台兼容性
Vue2 | Vue3 |
---|---|
× | √ |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 4.51 app-vue app-uvue | × | √ | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 | 鸿蒙元服务 |
---|---|---|---|---|
× | × | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | × | × | × | × |
lime-tree 树
- 多层次的结构列表
- 插件依赖
lime-shared
,lime-style
,lime-checkbox
,lime-loading
不喜勿下
安装
插件市场导入即可,首次可能需要重新编译
代码演示
基础用法
通过data
设置树的节点数据
<l-tree
:data="data"
:default-expanded-keys="defaultExpandedKeys"
expand-on-click
checkable />
function repeat(count : number, value ?: any) : any[] {
const result : any[] = [];
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 defaultExpandedKeys = ['40', '41']
自定义 key 和 label 的字段
通过key-field
,label-field
,children-field
设置树节点字段
<l-tree
:data="customData"
:default-expanded-keys="defaultExpandedKeys"
key-field="id"
label-field="name"
children-field="items"
selectable />
function repeat(count : number, value ?: any) : any[] {
const result : any[] = [];
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 {
name: createLabel(level),
id: key,
items: createData(level - 1, key)
}
})
}
const data = ref(createData());
const defaultExpandedKeys = ['40', '41']
级联选择
设定 cascade
进行级联选择。
<l-tree
:data="data"
cascade
:default-expanded-keys="defaultExpandedKeys"
:default-checked-keys="defaultCheckedKeys"
@checked="updateCheckedKeys"
checkable />
function repeat(count : number, value ?: any) : any[] {
const result : any[] = [];
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 defaultExpandedKeys = ref(['40', '4030', '403020'])
const defaultCheckedKeys = ref(['40302010'])
const updateCheckedKeys = (keys : any[]) => {
console.log('keys', keys)
}
搜索
树接受 pattern
来完成搜索。showIrrelevantNodes
可以设置只显搜索节点
<input type="text"
style="background-color: #eee; padding: 10px; height: 50px;" placeholder="输入节点名称"
v-model="pattern" />
<view style="flex-direction: row; padding: 10px; align-items: center;">
<switch :checked="showIrrelevantNodes" @change="switch2Change"/>
<text v-show="!showIrrelevantNodes">隐藏搜索无关的节点</text>
<text v-show="showIrrelevantNodes">显示所有节点</text>
</view>
<l-tree
:data="searchData"
expandOnClick
cascade
:pattern="pattern"
:allow-checking-not-loaded="true"
:showIrrelevantNodes="showIrrelevantNodes">
</l-tree>
const showIrrelevantNodes = ref(false)
const pattern = ref('')
const searchData = [
{
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' }
]
}
]
},
{
label: '1',
key: '1',
children: [
{
label: '1-0',
key: '1-0',
children: [
{ label: '1-0-0', key: '1-0-0' },
{ label: '1-0-1', key: '1-0-1' }
]
},
{
label: '1-1',
key: '1-1',
children: [
{ label: '1-1-0', key: '1-1-0' },
{ label: '1-1-1', key: '1-1-1' }
]
}
]
}
]
const switch2Change = (event : UniSwitchChangeEvent) => {
showIrrelevantNodes.value = event.detail.value
}
异步加载
使用 load-node
回调来加载数据。异步加载时,所有 isLeaf
为 false
并且 children
不为数组的节点会被视为未加载的节点。
<l-tree
loadingColor="red"
:data="asyncData"
cascade
:checked-keys="checkedKeys"
:expanded-keys="expandedKeys"
:load-node="handleLoad"
:allowCheckingNotLoaded="true"
@checked="handleCheckedKeysChange"
@expanded="handleExpandedKeysChange"
checkable />
function nextLabel(currentLabel ?: any) : string {
if (currentLabel == null)
return 'Out of Tao, One is born'
if (currentLabel == 'Out of Tao, One is born')
return 'Out of One, Two'
if (currentLabel == 'Out of One, Two')
return 'Out of Two, Three'
if (currentLabel == 'Out of Two, Three') {
return 'Out of Three, the created universe'
}
if (currentLabel == 'Out of Three, the created universe') {
return 'Out of Tao, One is born'
}
if (currentLabel != null) {
return `${currentLabel}`
}
return ''
}
function createData() : UTSJSONObject[] {
return [
{
label: nextLabel(null),
key: 1,
isLeaf: false
},
{
label: nextLabel(null),
key: 2,
isLeaf: false
}
]
}
const expandedKeys = ref<string[]>([])
const checkedKeys = ref<string[]>([])
const asyncData = ref(createData())
const handleLoad = (node : UTSJSONObject) : Promise<boolean> => {
return new Promise<boolean>((resolve) => {
setTimeout(() => {
console.log(`node['label']`, node['label'])
node.children = [
{
label: nextLabel(node['label']),
key: `${node['key']}${nextLabel(node['label'])}`,
isLeaf: false
}
]
resolve(true)
}, 1000)
})
}
const handleExpandedKeysChange = (keys : string[]) => {
console.log('handleExpandedKeysChange keys', keys)
expandedKeys.value = keys
}
const handleCheckedKeysChange = (keys : string[]) => {
console.log('handleCheckedKeysChange', keys)
checkedKeys.value = keys
}
自定义内容
可以通过switcher
插槽设置展开收缩的图标,content
插槽自定义内容,导出的node
为节点原始数据。
<l-tree
:data="data"
checkboxPlacement="right"
expand-on-click
center
checkedColor="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 class="logo" style="width: 30px; height: 30px;" src="https://img-cdn-tc.dcloud.net.cn/uploads/avatar/000/12/54/99_avatar_max.jpg?=1615885669"></image>
<text style="padding: 10px;">{{node['label']}}公司</text>
</view>
</template>
</l-tree>
function repeat(count : number, value ?: any) : any[] {
const result : any[] = [];
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());
查看示例
- 导入后直接使用这个标签查看演示效果
// 代码位于 uni_modules/lime-tree/compoents/lime-tree
<lime-tree />
插件标签
- 默认 l-tree 为 component
- 默认 lime-tree 为 demo
关于vue2的使用方式
- 插件使用了
composition-api
, 如果你希望在vue2中使用请按官方的教程vue-composition-api配置 - 关键代码是: 在main.js中 在vue2部分加上这一段即可.
// vue2
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
API
Props
参数 | 说明 | 类型 | 默认值 | |
---|---|---|---|---|
cascade | 是否关联选项 | boolean | false |
|
checkStrategy | 设置勾选策略来指定勾选回调返回的值,all 表示回调函数值为全部选中节点;parent 表示回调函数值为父节点(当父节点下所有子节点都选中时);child 表示回调函数值为子节点 | string | all |
|
checkable | 是否显示选择框 | boolean | false |
|
checkboxPlacement | 复选框的位置,'left' | 'right' | string | left |
childrenField | 替代 TreeOption 中的 children 字段名 | string | children |
|
keyField | 替代 TreeOption 中的 key 字段名 | string | key |
|
labelField | 替代 TreeOption 中的 label 字段名 | string | label |
|
disabledField | 替代 TreeOption 中的 disabled 字段名 | string | disabled |
|
checkedKeys | 受控的选中多选项 | string | number | - |
|
data | 树节点数据 | Object[] | - |
|
defaultCheckedKeys | 默认选中多选项 | (string | number)[] | - |
|
defaultExpandedKeys | 默认展开项 | (string | number)[] | - |
|
expandedKeys | 受控的展开项 | (string | number)[] | - |
|
expandOnClick | 允许点击节点展开/收缩 | boolean | false |
|
checkOnClick | 允许点击节点勾选 | boolean | false |
|
loadNode | 异步加载回调 | (node: Object) => Promise |
`` | |
pattern | 搜索内容 | string | `` | |
showIrrelevantNodes | 搜索时显示无关节点 | boolean | true |
|
allowCheckingNotLoaded | 允许勾选未加载节点 | boolean | false |
|
indentWidth | 缩进宽度 | number | 24 |
|
center | 节点内容垂直居中 | boolean | false |
|
loadingColor | loading颜色 | string | - |
|
checkedColor | checkebox选中颜色 | string | - |
|
rotatableSwitcher | checkebox选中颜色 | boolean | false |
Events
事件名 | 说明 | 回调参数 |
---|---|---|
update:checked-keys | 勾选触发 | (keys: Key[]) |
checked | 勾选触发 | (keys: Key[]) |
update:expanded-keys | 展开触发 | (keys: Key[]) |
expanded | 展开触发 | (keys: Key[]) |
click | 点击触发 | (node: object, siblings: object[]) |
Slots
名称 | 说明 |
---|---|
switcher | 展开收缩图标插槽: { hide : boolean, loading: boolean, expanded: boolean} |
content | 节点内容插槽: { node : Object } |
打赏
如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。