话不多说,先上效果图:

小程序实现Treeview树多选功能

实现思路

源数据结构

首先我们的数据结构大概是:

[{"id": "0","name": "动物分类","pid": "-1","children": [{"id": "1","name": "哺乳动物","pid": "0","children": [{"id": "3","name": "狗","pid": "1","children": []},{"id": "4","name": "猫","pid": "1","children": []},{"id": "5","name": "大象","pid": "1","children": []}]},{"id": "2","name": "鸟类","pid": "0","children": [{"id": "6","name": "喜鹊","pid": "2","children": []},{"id": "7","name": "麻雀","pid": "2","children": []},{"id": "8","name": "乌鸦","pid": "2","children": []}]}]}
]

其中id和pid方便进行父子节点的关系确定,不管服务器提供给我们的数据结构是怎样的,这两项必不可少。
同时,由于不同开发者的数据的内容会存在差异,所以我们需要定义一个通用的Node对象,将用户数据改为统一的标准对象方便操作。如下:

 /*** 创建Node对象*/createNode(id, pid, lable) {let node = new Object();//节点idnode.id = id;//父节点idnode.pid = pid;//文字node.lable = lable;//上一级Node(实际是记录父节点的索引的值)node.parentNode = null;//下一级子node的数据数组(实际是记录子节点的索引的值)node.childrenNode = [];//是否展开node.isExpand = false;//icon图标(+,-)node.icon = -1;//当前的级别(层级)node.level = 0//checkbox是否选中node.checkbox = false;//自己的索引值node.index = -1;return node;},

注意:至于为什么parentNode和childrenNode 的属性值为什么是记录索引而不是对象,是因为小程序的setData方法在将js数据发送给wxml页面时,是需要调用JSON.stringify()转为json字符串,而我们如果parentNode或childrenNode的值为对象时,会存在对象关系的引用,会报循环引用的错误,进而调用栈溢出异常.暂时没有想到好的解决版本,只能曲线救国了,通过索引来找到具体的Node对象.有知道更好的解决办法的小伙伴可以讨论一下。

将源数据转为通用的Node的数组并排序确立父子关系

转化为通用的Node数组并排序

转化为通用的Node数组并排序并不难,我们将服务器给我们的数据通过递归循环调用,放入到Node的Array中。
部分代码如下:

    getAllNodes(convertedNodesArray, array) {array.forEach(function (ele) {//转化为node对象let nodedata = _this.createNode(ele.id, ele.pid, ele.name);//存入数组中convertedNodesArray.push(nodedata)//如果有子节点继续递归调用if (ele.children.length > 0) {_this.getAllNodes(convertedNodesArray, ele.children);}})},

通过这个递归调用,我们集合中的数据项,应该是 [动物分类,哺乳动物,狗,猫,大象,鸟类,麻雀,喜鹊,乌鸦];已经有了顺序了

确立父子关系

将数据放到Node数据并排序比较容易,但如何确立父子关系(也就是给node的childNode和parenNode赋值)呢?解决方法是:循环比较当前节点和当前节点往后的所有节点一一进行比对:

  for (let i = 0; i < convertedNodes.length; i++) {//当前节点let node = convertedNodes[i];node.index = i;for (let j = i + 1; j < convertedNodes.length; j++) {//下一个节点let nextNode = convertedNodes[j];if (nextNode.pid == node.id) {//将子节点的索引添加到自己的childrenNode数组中node.childrenNode.push(j)//给子节点添加父节点的索引nextNode.parentNode = i;} else if (nextNode.id == node.pid) {nextNode.childrenNode.push(i);node.parentNode = j;}}}

通过上面的操作,我们现在获取的数据都是排序且已经有了父子关系的了(数据平级展示)。
####过滤出可见的Node数组
我们的数据在排序后,并不是所有的数据都要展示,所以需要过滤出可以见的Node数组,真正展示到页面的数据(默认展示第一级数据),还记得我们的Node中有一个isExpand属性,这个属性值决定是否展示当前Node节点,默认为false,只有父节点的isExpand状态为true,子节点的isExpand才为true.还有一个属性是parentNode,默认为null,只有根节点的parentNode才为null,我们根据这两个属性值进行判断,相关代码如下:

        for (let i = 0; i < nodes.length; i++) {let node = nodes[i];//根节点或父节点展开的子节点(相对)都属于可见nodeif (_this.isRoot(node) || _this.isParentExpand(nodes, node)) {//设置左侧的图标为可展开_this.setParentNodeIcon(node)result.push(node);}}//判断父节点是否展开isParentExpand(nodes, node) {//如果是根节点if (node.parentNode == null) {return false;}//获取父节点的索引,判断父节点是否打开return nodes[node.parentNode].isExpand;},// 是否为根节点isRoot(node) {//根据是否有父节点判断是否是根节点return node.parentNode == null},

关于复选框

关于复选框的逻辑是:如果用户点击的复选框是父节点,那么对应的子节点都要选中,同样的,如果子节点全部选中,那么父节点要自动勾选.实现思路是:递归调用判断,改变Node的checkbox值,然后过滤出可见node数组,再setdata更新列表.

关于展开关闭列表

同复选框的实现思路和逻辑一致.

####总结
我已经将TreeView作为一个Component组件使用了,点击确定按钮后,会返回所有的数据及状态,使用者只需要根据自己的需求过滤出想要的数据展示即可.详情请查看代码。

TreeView多选框(赞助点积分)
TreeView多选框(github免费)

小程序实现TreeView树多选功能相关推荐

  1. 微信小程序实现单选、全选功能

    前言概述 本文介绍微信小程序实现单选.全选功能,效果如下: 实现过程 1.先实现页面效果,文件*.wxml和*.wxss代码如下: <view class="container&quo ...

  2. 微信小程序开发教程第八章:微信小程序分组开发与左滑功能实现

    接着上面微信小程序开发教程第八章:微信小程序分组开发与左滑功能实现.(第一二章:微信小程序开发教程,第三四章:微信小程序项目结构以及配置&微信小程序首页面开发,第五章:微信小程序名片夹详情页开 ...

  3. 微信小程序图标不支持html,微信小程序实现自定义加载图标功能

    效果图 实现思路 1.首先通过HTML+CSS实现加载动画的静态效果: 2.根据需求给每个动画设计不同的动画效果. 例如第一个加载图标的静态绘制 1.首先确定动画的盒子宽高: 2.设置盒子中每一个长方 ...

  4. 外卖菜谱小程序源码-带流量主功能-外卖领劵个人也可过审

    简介: 站长点评:这套小程序优点就带很多菜谱,各种你爱吃菜的做法与各类食材介绍营养搭配,相信很多小姐姐会感兴趣. 宝妈宝爸这个小程序肯定能留的住这个群体的人脉流量,这是小程序最大的亮点:其它功能也没有 ...

  5. 腾讯微信支付支持全量商家小程序场景开通云闪付功能

    为持续推进支付生态开放及合作,腾讯宣布与银联云闪付互联互通再次取得重大进展: 微信支付于12月15日开始逐步升级商家小程序支持云闪付付款功能,微信商家小程序已全面开通云闪付.该功能升级后,用户即可在已 ...

  6. 微信授权绑定手机号 java_微信小程序获取手机号授权用户登录功能

    小程序中有很多地方都会用到注册用户信息的地方,用户需要填写手机号等,有了这个组件可以快速获取微信绑定手机号码,无须用户填写. 1.getPhoneNumber这个组件通过button来实现(别的标签无 ...

  7. 微信小程序开发(2) - 微信小程序实现拍照和录像拍摄功能方法

    微信小程序开发2 - 本文实例讲述了微信小程序实现拍照和录像拍摄功能方法.分享给大家供大家参考,具体如下: 微信小程序拍照: API:wx.chooseImage 原先的想法是使用微信的camera组 ...

  8. wifi 小程序 透传_微信小程序实现的一键连接wifi功能示例

    本文实例讲述了微信小程序实现的一键连接wifi功能.分享给大家供大家参考,具体如下: 在已知wifi账号和wifi密码的情况下,一般采用以下的流程来连接wifi Wi-Fi 接口调用: 1.Andro ...

  9. 【微信小程序/实现】实现留言墙功能页面

    [微信小程序/实现]实现留言墙功能 一.需求分析 二.功能设计 三.页面设计 四.代码 (一)核心代码:向服务器发出请求 (二)完整代码 message.wxml message.wxss messa ...

最新文章

  1. 最长有效括按号长度(利用栈解决java语言)
  2. XP`开机速度慢的解决方法
  3. No module named 'pandads'
  4. 宝塔挂载linux硬盘,宝塔移动硬盘挂载Linux服务器挂载ntfs移动硬盘
  5. yaml格式,给Java类绑定数据
  6. 钱线观察:货币基金T+0驾到 活期存款将死?
  7. 5.1.3 SELECT+INNER JOIN读取数据
  8. failed to execute ‘dot‘, make sure the Graphviz executables are on your systems‘ PATH
  9. ASP.NET统计图表控件
  10. python创建按钮command怎么用,python按钮调用函数
  11. 给定一个无重复元素的数组 candidates 和一个目标数 target .
  12. October 2019 Twice SQL Injection
  13. 破局:技术视野与规划
  14. ZJUT 2012校赛决赛-涂颜色
  15. 【转自心声】华为眼中管理者的18种惰怠行为
  16. 解读MT7620A上的DTS文件
  17. usaco3.2.4 Feed Ratios
  18. iOS开发之自定义键盘(数字,字母类型等随意切换)
  19. 物理服务器安装CentOS 7操作系统
  20. TikTok搬运视频怎么才会不被限流?

热门文章

  1. HBuilder 连接 Nox 夜神模拟器 adb命令不是内部或外部命令 解决方案
  2. 数据透视表+函数搞定Excel中的非重复计数
  3. hashmap1.7头插法造成死循环的原因分析
  4. 计算机毕业优秀作品展观后感,优秀作业展观后感作文
  5. 如何用3D软件做好人头建模?
  6. amazon web services的一些知识
  7. [ArcGIS] 空间分析(十一)ArcGIS眼中的3D世界 -3D折线
  8. 恢复chrome浏览器首页
  9. shell中spawn什么意思_shell 编程-Expect
  10. 计算机学科知识与教学能力初级中学,2021年中小学教师资格考试《信息技术》学科知识与教学能力 试题分析...