小程序二叉树级菜单选择组件

.wxml 文件

<view wx:for="{{tree}}" wx:key="id" class="tree-container">
  <view class="tree-item">
    <text class="iconfont {{item.open ? '+' : '-'}} tree-dropdown" data-index="{{index}}" bindtap="trigger" />
    <text class="tree-lable" data-info="{{item}}" bindtap="handleSelect">{{item[label]}}</text>
    <text wx:if="{{value == item[selectKey]}}" class="iconfont icon-selected tree-selected"></text>
  </view>

  <!-- 二级菜单 -->
  <tree wx:if="{{item.open && item[children] && item[children].length > 0 }}" dataTree='{{ item[children] }}' label="{{label}}" children="{{children}}" model:value="{{value}}" selectKey="{{selectKey}}" bind:select="chilrenSelect" />
</view>

.json 文件

{
  "component": true,
  "usingComponents": {
    "tree": "/components/customComponents/tree"
  }
}

.js 文件

Component({
  options: {
    addGlobalClass: true,
  },
  properties: {
    dataTree: { // 树形结构数据
      type: Array,
      value: []
    },
    value: { // 选择值
      type: String,
      value: ''
    },
    selectKey: { // 选择字段属性
      type: String,
      value: 'id'
    },
    label: { // 显示名称属性
      type: String,
      value: 'name'
    },
    children: { // 子级属性
      type: String,
      value: 'children'
    },
    open: { // 是否展开全部节点(数据中open优先)
      type: Boolean,
      value: false
    }
  },
  observers: {
    'dataTree': function (params) {
      this.setData({
        tree: this._initData(params)
      })
    }
  },
  data: {
    tree: []
  },
  methods: {
    _initData (nodes) {
      nodes.forEach(el => {
        if (el.open == undefined) el.open = this.properties.open // 是否展开
        const children = this.properties.children
        if (el[children] && el[children].length > 0) el[children] = this._initData(el[children])
      })
      return nodes
    },
    // 选择事件
    handleSelect (e) {
      const info = e.currentTarget.dataset.info
      let value = ''
      if (info[this.data.selectKey] != this.data.value) value = info[this.data.selectKey]
      // 更新选择
      this.setData({ value })
      this.triggerEvent('select', info)
    },
    // 选择冒泡事件
    chilrenSelect (e) {
      const data = e.detail
      this.triggerEvent('select', data)
    },
    // 展开、收起
    trigger (e) {
      const index = e.target.dataset.index
      this.data.tree[index].open = !this.data.tree[index].open
      this.setData({ tree: this.data.tree })
    }
  }
})

.wxss 文件

.tree-container {
  display: flex;
  flex-direction: column;
  padding-left: 24rpx;
}

.tree-item {
  display: flex;
}

.tree-dropdown {
  padding: 24rpx;
  font-size: 32rpx;
}

.tree-lable {
  flex: 1;
  line-height: 3;
  font-size: 28rpx;
  max-width: 510rpx;
}

.tree-selected {
  color: #18C984;
  font-size: 50rpx;
  padding: 12rpx 24rpx;
}

使用方式

<view>
	<tree dataTree="{{tree}}" model:value="{{value}}"/>
</view>
data: {
	value:'',
	tree: [
      {
        id: 1,
        name: '001',
        open: true,
        children: [{
          id: 2,
          name: '001-01',
          children: [{
            id: 3,
            name: '001-01-01',
            children: []
          }]
        }]
      }
    ]
}

总结:

1、小程序中未提供元素节点动态插入,不能 js 动态挂载元素 (只提供节点信息查询方式)。
2、树形菜单核心在于递归,本组件用组件调用自身实现递归。
3、组件在这里只实现单选 √ ,需要多选的自行发挥

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值