前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序自用Tree树形控件

微信小程序自用Tree树形控件

作者头像
骤雨重山
发布2022-01-17 09:49:53
2.4K0
发布2022-01-17 09:49:53
举报
文章被收录于专栏:骤雨重山

使用有赞的vant组件库开发微信小程序过程中,使用到了tree树形控件,但vant组件库无此组件,所以手撸了一个简陋二级tree树形控件

功能包含

全选按钮功能、反选按钮功能 父级列表前的开关icon 子级列表的选中的禁止或启用 父级列表显示子级列表可选数量 父级下所有可选子级选中则父选中(禁用状态不算) 使用了van-collapse组件带有折叠关闭动画效果 ...

效果展示

微信小程序自Tree树形控件 WXML代码部分

代码语言:javascript
复制
<van-collapse value="{{ activeNames }}" bind:change="onChange">
    <block wx:for="{{wrongList}}" wx:for-item="itm" wx:key="index">
      <van-collapse-item name="{{itm.code}}" data-hans="itm.code">
        <view slot="title">
          <image src="https://xxxx/{{KG[itm.code]!=true ?'open':'close'}}.png"
            style="width:20rpx" mode="widthFix" />
          {{itm.name}}
          <view catchtap="catchtap">
            <van-checkbox class="fuCheck" disabled="{{tempCodeArr[itm.code].length==0}}"
              value="{{ checkedAll[itm.code] }}" data-hans="{{itm.code}}" bind:change="checkcheck" />
            <view class="counts" style="right:106rpx">({{itm.fallibleCount}})</view>
          </view>
        </view>
        <view class="items">
          <van-checkbox-group value="{{ choisObj[itm.code] }}" data-hanscode="{{itm.code}}" bind:change="checkChange">
            <van-cell-group>
              <block wx:if="{{!_itm.hansFu}}" wx:for="{{ itm.children }}" wx:for-index="_index" wx:for-item="_itm"
                wx:key="code">
                <van-cell title="{{ _itm.name }}" value-class="value-class" clickable>
                  <van-checkbox name="{{ _itm.code }}" disabled="{{_itm.fallibleCount=='0'?true:false}}" />
                  <view class="counts">({{_itm.fallibleCount}})</view>
                </van-cell>
              </block>
            </van-cell-group>
          </van-checkbox-group>
        </view>
      </van-collapse-item>
    </block>
  </van-collapse>

微信小程序自Tree树形控件 JS部分

代码语言:javascript
复制
/*
 * @Author: Han
 * @Date: 2021-01-04 14:18:09
 * @LastEditors: Han
 * @LastEditTime: 2021-01-04 15:07:09
 * @FilePath: \wechat-app\tree.js
 */
import {
  get
} from 'api'
Page({
  data: {
    // 父级按钮合集
    checkedAll: [],
    // 面板状态合集
    activeNames: [],
    // 章节List
    wrongList: [],
    // 选中的子节点合集
    choisObj: {},
    // 临时 父 子 数组
    tempCodeArr: {},
    // 全选按钮状态
    selectAllStatus: true
  },
  // 全选事件
  selectAll() {
    const _this = this
    const status = this.data.selectAllStatus
    const okTempCodeArr = JSON.parse(JSON.stringify(_this.data.tempCodeArr))
    Object.keys(okTempCodeArr).forEach(itm => {
      okTempCodeArr[itm].length == 0 && delete okTempCodeArr[itm]
    })
    // 模拟点击
    Object.keys(okTempCodeArr).forEach(itm => {
      _this.checkChange({
        currentTarget: {
          dataset: {
            hanscode: itm
          }
        },
        detail: status ? okTempCodeArr[itm] : []
      })
    })
    this.setData({
      selectAllStatus: !status,
    })
  },
  // 父级按钮
  checkcheck(e) {
    const codes = e.currentTarget.dataset.hans
    // 判断父级按钮状态
    this.setData({
      checkedAll: {
        ...this.data.checkedAll,
        [codes]: e.detail
      },
      choisObj: {
        ...this.data.choisObj,
        [codes]: e.detail ? this.data.tempCodeArr[codes] : []
      }
    });
    // 去除空对象,并设置按钮状态
    const tempObj = this.data.choisObj
    Object.keys(tempObj).forEach(itm => {
      tempObj[itm].length == 0 && delete tempObj[itm]
    })
    this.setData({
      choisObj: tempObj,
      btnStatus: Object.keys(tempObj).length > 0
    })
  },
  // 子级按钮点击选中或非事件
  checkChange(e) {
    const codes = e.currentTarget.dataset.hanscode
    // 可选中的是否全选
    const status = e.detail.length == this.data.tempCodeArr[codes].length
    this.setData({
      choisObj: {
        ...this.data.choisObj,
        [codes]: e.detail
      },
      checkedAll: {
        ...this.data.checkedAll,
        [codes]: status
      }
    });
    const tempObj = this.data.choisObj
    Object.keys(tempObj).forEach(itm => {
      tempObj[itm].length == 0 && delete tempObj[itm]
    })
    this.setData({
      choisObj: tempObj,
      btnStatus: Object.keys(tempObj).length > 0
    })
  },
  // 折叠面板切换事件
  onChange(event) {
    let tempArr = []
    // 当前面板折叠状态 临时变量
    let key = false

    // 由于面板可以多个同时展开,所以 👇
    // 控制面板标题前 图片的 + 或 -
    if (this.data.activeNames.length > event.detail.length) {
      // 深拷贝
      tempArr = JSON.parse(JSON.stringify(this.data.activeNames))
      event.detail.forEach(itm => {
        const n = tempArr.indexOf(itm);
        n != -1 && tempArr.splice(n, 1)
      });
      key = false
    } else {
      tempArr = JSON.parse(JSON.stringify(event.detail))
      this.data.activeNames.forEach(itm => {
        const n = tempArr.indexOf(itm);
        n != -1 && tempArr.splice(n, 1)
      });
      key = true
    }
    this.setData({
      activeNames: event.detail,
      KG: {
        ...this.data.KG,
        [tempArr[0]]: key
      }
    });
  },
  // 切换事件
  onSwitchChange(e) {
    // 切换时,清空除额外所有数据
    this.setData({
      xx: [],
      xx: {},
      ...xx
    })
    // 之后重新获取列表
    this.XXX();
  },

  // 获取书本信息
  async getBookArr() {
    wx.showLoading({
      title: '获取数据中',
    })
    let tempArr = [];
    const _this = this
    const {
      ret: {
        bookList: _res
      }
    } = await get('api');
    wx.hideLoading()
    // 书本信息赋给下拉框
    Array.isArray(_res) && _res.forEach(itm => {
      tempArr.push({
        'text': itm.name,
        'value': itm.id
      })
    })
    tempArr.length > 0 && _this.setData({
      bookDataArr: tempArr
    })
  },
  // 获取章节列表
  async getWrongList() {
    const _this = this
    const _res = await get(`api`)
    let _tempArr = _res.ret.bookCatalogs;
    // 章节数据处理
    Array.isArray(_tempArr) && _tempArr.length > 0 && _tempArr.forEach((itm, idx) => {
      let tempArrs = []
      itm.fallibleCount = Number(itm.fallibleCount)
      itm.children.length > 0 ? itm.children.forEach(_itm => {
        itm.fallibleCount += Number(_itm.fallibleCount)
        _itm.fallibleCount != '0' && tempArrs.push(_itm.code)
      }) : _tempArr[idx].children.push({
        name: itm.name,
        code: itm.code,
        fallibleCount: itm.fallibleCount,
        hansFu: true
      })
      _this.setData({
        tempCodeArr: {
          ..._this.data.tempCodeArr,
          [itm.code]: tempArrs
        }
      })
    })
    _res.ret && this.setData({
      wrongList: _tempArr
    })
  },
  // 防止父级点击事件冒泡空事件
  catchtap() {}
})
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 功能包含
  • 效果展示
  • 微信小程序自Tree树形控件 WXML代码部分
  • 微信小程序自Tree树形控件 JS部分
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档