第一次在uniapp项目里看到tki-tree这个树形选择器组件时,我正遇到一个头疼的需求:需要让用户在省市县三级结构中选择收货地址。当时尝试了好几种方案都不理想,直到发现了这个宝藏组件。tki-tree最吸引我的地方是它完美支持多级嵌套数据展示,而且配置简单,就像搭积木一样容易上手。
这个组件本质上是一个增强版的树形选择器,支持单选、多选、父级选择等多种交互模式。我在电商项目里实测发现,它能轻松处理5级以上的数据层级,而且渲染速度比原生picker快不少。对于需要处理行政区划、组织架构、商品分类这类层级数据的场景,简直是救命稻草。
安装过程特别简单,直接从DCloud插件市场获取组件文件,放在项目commons目录下就行。我习惯把这类通用组件都放在commons文件夹里统一管理,这样不同页面都能方便调用。第一次引入时可能会遇到路径问题,记得检查import语句的路径是否正确,这是新手最容易踩的坑。
配置tki-tree就像组装乐高积木,三个核心部件缺一不可。首先是组件注册,在页面的script部分加入这段代码:
javascript复制import tkiTree from "@/commons/tki-tree/tki-tree.vue"
export default {
components: { tkiTree }
}
然后是模板部分,基础结构长这样:
html复制<tki-tree
ref="tkitree"
:range="treeData"
rangeKey="name"
confirmColor="#4e8af7"
/>
这里有个小技巧:ref属性一定要设置,后面通过this.$refs调用组件方法时会用到。rangeKey指定了显示文本对应的字段名,比如你的数据里用"label"而不是"name",这里就要相应调整。
最后是数据准备,建议在data里初始化一个空数组:
javascript复制data() {
return {
treeData: []
}
}
我遇到过最典型的问题就是数据格式不对。tki-tree要求的数据结构必须是嵌套children的数组,就像这样:
javascript复制const areaData = [
{
id: 1,
name: '北京市',
children: [
{
id: 11,
name: '朝阳区',
children: [
{ id: 111, name: '三里屯街道' }
]
}
]
}
]
新手常犯两个错误:一是忘记写children字段,二是children写成字符串而不是数组。建议先用简单的2-3级数据测试,确认没问题再扩展复杂结构。
最近做员工选择器时,发现个实用技巧:通过设置selectParent属性,可以控制是否允许选择父节点。比如部门选择场景,我们可能只允许选具体人员:
html复制<tki-tree
:selectParent="false"
:range="deptData"
/>
而商品分类场景可能需要选择父级分类:
html复制<tki-tree
:selectParent="true"
:range="categoryData"
/>
多选模式更强大,设置multiple为true后,配合max参数可以限制最大选择数量:
html复制<tki-tree
:multiple="true"
:max="3"
/>
当处理大型组织架构时,我推荐使用懒加载技术。先在顶层加载部门数据,点击时再异步获取下级数据:
javascript复制async loadChildren(node) {
const res = await api.getDeptChildren(node.id)
this.$refs.tkitree.updateChild(node.id, res.data)
}
记得在组件上添加lazy属性:
html复制<tki-tree
:lazy="true"
@lazy-load="loadChildren"
/>
这种方法首次加载时间能减少70%以上,特别适合移动端场景。
去年做一个万级城市的项目时,遇到了严重卡顿。后来通过分片加载解决了:首次只加载省级数据,选择省份后加载该省下的城市。关键代码:
javascript复制onLoad() {
this.loadProvince()
},
methods: {
async loadProvince() {
this.treeData = await api.getProvinceList()
},
async handleConfirm(selected) {
if(selected.level === 1) {
const cities = await api.getCityList(selected.id)
this.$refs.tkitree.updateNode(selected.id, { children: cities })
}
}
}
这几个优化手段亲测有效:
虚拟滚动配置示例:
html复制<tki-tree
:virtual-scroll="true"
:item-size="44"
/>
item-size建议设置为实际项目中的行高,这样滚动条精度更高。
这个问题困扰了我整整一天。后来发现需要用this.$nextTick确保DOM更新:
javascript复制this.treeData = newData
this.$nextTick(() => {
this.$refs.tkitree.refresh()
})
想修改箭头图标?覆盖这个CSS类就行:
css复制.tki-tree-arrow {
background-image: url('/static/your-arrow.png');
width: 12px;
height: 12px;
}
主题色修改更简单,直接传confirmColor属性:
html复制<tki-tree
confirmColor="#FF0000"
/>
去年给某物流公司做的调度系统里,我用tki-tree实现了三级地址选择+仓库选择的复合功能。关键是在confirm事件中处理多维度数据:
javascript复制selectLocation(e) {
const [province, city, warehouse] = e
this.form.provinceId = province.id
this.form.cityCode = city.code
this.form.warehouseId = warehouse ? warehouse.id : null
}
模板部分需要注意设置multiple为false(默认就是false),因为这是级联选择而非多选。