微信小程序自定义tree组件,拿走直接用

工作原因,微信小程序需要一个功能类似于elemenui中的tree组件,找了好多ui组件库没有能直接用的,最后自己写了一套,封装成组件,中心技术是组件本身递归,只需要在父级页面传“树列表数据”和“选中的节点id”就可以用了。

tree组件

tree.wxml
<!--common/tree/tree.wxml-->
<view wx:for="{{tree}}" wx:key="deptId">
  <!-- 一级 -->
  <view style="margin-left: {{treeListIndex*24}}rpx" >
    <view  class="tree-item">
      <view bindtap="isOpen" data-index="{{index}}" wx:if="{{item.children && item.children.length > 0 || item.userList && item.userList.length>0}}" class="iconfont {{item.open ? 'icon-out' : 'icon-in'}}" style="color: #E6A23C;"></view>
      <view class="iconfont icon-in" wx:else style="color: #E6A23C;"></view>
      <view class="tree-item-name" >
        <text class="tree-item-title">{{item.deptName}}</text>
      </view>
    </view>
    <view wx:if="{{item.userList && item.userList.length>0 && item.open}}" class="tree-user-item" >
      <view wx:for="{{item.userList}}" wx:key="userId" class="tree-user-item-item" catchtouchmove="preventD" catchtap="select" data-item="{{item}}" data-index="{{index}}">
        <view class="tree-user-avater-item" >
          <view>{{item.nickName}}</view>
          <view>{{item.nickName}}</view>
        </view>
        <view class="iconfont icon-selin" wx:if="{{item.status == 1}}" style="color: #2677FC;"></view>
        <view class="iconfont icon-selout" wx:if="{{item.status == 0}}"></view>
      </view>
    </view>
  </view>
  <tree wx:if="{{item.children && item.children.length > 0 && item.open }}" ids="{{ ids }}"  treeData='{{ item.children }}' bind:getIds="nodeGetIds" data-index="{{index}}" data-node="{{item.children}}"  isOpenAll="{{true}}" treeListIndex="{{treeListIndex+1}}" />
</view>

tree.js
// common/tree/tree.js
const app = getApp()
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    treeData: {
      type: Array,
      value: []
    },
    ids: {
      type: Array,
      value: [],
    },
    treeListIndex: {
      type: Number,
      value: 1
    },
    isOpenAll: { // 是否展开全部节点
      type: Boolean,
      value: true
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    tree: [],
  },
  observers: {
    'treeData':function(params) {
      this.setData({
        tree: this._init(params)
      })
    },
    'ids':function(params) {
      this.setData({
        tree: this._uploadTree(params, this.data.tree)
      })
    },
  },
  /**
   * 组件的方法列表
   */
  methods: {
    isOpen(e) {
      const open = 'tree[' + e.currentTarget.dataset.index + '].open'
      this.setData({
        [open]: !this.data.tree[e.currentTarget.dataset.index].open
      })
    },
    _init(node) {
      let that = this;
      node.forEach(element => {
        if(element.checked == undefined) element.checked = 0;
        element.open = this.properties.isOpenAll;
        if(element.children && element.children.length > 0) element.children = this._init(element.children)
      })
      return node
    },
    _uploadTree(ids, tree){
      tree.forEach(element => {
        if(element.userList && element.userList.length > 0) {
          element.userList.forEach(r => {
            if(ids.indexOf((Number(r.userId))) > -1) {
              r.status = 1
            } else {
              r.status = 0
            }
          })
        }
      })
      return tree
    },
    // 选择
    select(e) {
      let item = e.currentTarget.dataset.item
      this.triggerEvent('getIds', item.userId)
    },
    nodeGetIds(e) {
      this.triggerEvent('getIds', e.detail)
    }
  }
})

tree.wxss
/* common/tree/tree.wxss */
@import "/utils/iconFont.wxss";
.tree-item{
  display: flex;
  align-items: center;
  margin: 10rpx 0;
}
.tree-item-name{
  margin-left: 20rpx;
}
.tree-item-title{
  font-size: 32rpx;
  color: #303133;
}

.tree-user-item{
  /* display: flex;
  align-items: center; */
  margin: 20rpx 0;
  box-sizing: border-box;
}
.tree-user-item-item{
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 30rpx 0;
}
.tree-user-avater-item{
  display: flex;
  align-items: center;
  font-size: 32rpx;
  color: #303133;
}
.tree-user-avater-item>view:nth-of-type(1) {
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
  font-size: 26rpx;
  color: #fff;
  text-align: center;
  line-height: 64rpx;
  margin-right: 10rpx;
  background-color: #2677FC;
}

tree.json
{
  "component": true,
  "usingComponents": {
    "tree": "/common/tree/tree"
  }
}

父级页面

sel-people.wxml
<tree treeData="{{treeData}}" ids="{{ids}}" treeListIndex="{{1}}" isOpenAll="{{true}}" bind:getIds="getIds"></tree>
sel-people.json
{
  "usingComponents": {
    "tree": "/common/tree/tree"
  }
}
sel-people.js
// pages/sel-people/sel-people.js
const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    contentHeight: app.globalData.contentHeight,
    navColor: '#fff',
    title: '',
    backStatus: true,
    // 模拟接包时候的json数据
    treeData: [
        {
            "deptId": "1", 
            "deptName": "经建", 
            "userList": [
                {
                    "userId": 1, 
                    "userName": "admin", 
                    "nickName": "管理员"
                }, 
                {
                    "userId": 2, 
                    "userName": "corner", 
                    "nickName": "星辰"
                }
            ], 
            "children": [
                {
                    "deptId": "2", 
                    "deptName": "弘德云", 
                    "userList": [
                        {
                            "userId": 3, 
                            "userName": "admin1", 
                            "nickName": "管理员1"
                        }, 
                        {
                            "userId": 4, 
                            "userName": "corner1", 
                            "nickName": "星辰1"
                        }
                    ], 
                    "children": [
                      {
                        "deptId": "3", 
                        "deptName": "招投标", 
                        "userList": [
                          {
                            "userId": 5, 
                            "userName": "admin1", 
                            "nickName": "管理员2"
                        }, 
                        {
                            "userId": 10, 
                            "userName": "corner1", 
                            "nickName": "星辰2"
                        }
                        ]
                      }
                    ]
                }
            ]
        }
    ],
    ids: [1]
  },
    
  getIds(e) {
// 判断tree组件传过来的id,选中or未选中
    let id = e.detail
    if(this.data.ids.indexOf(Number(id)) > -1) {
      this.data.ids.splice(this.data.ids.indexOf(Number(id)), 1)
    } else {
      this.data.ids.push(Number(id))
    }
    this.setData({
      ids: this.data.ids
    })
    console.log(this.data.ids)
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
  },

})

以下是tree组件需要的icon图标,自己去矢量库下载就好 

以下是成品图

 

 感谢大家!!!

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
自定义微信小程序的loading组件显示载入动画方法,可以按以下步骤进行: 1. 创建一个新的组件:首先,在小程序项目中创建一个新的组件,在组件目录下新建一个文件夹,例如命名为loading,在该文件夹下创建两个文件:loading.wxml和loading.wxss,用于编写组件的结构和样式。 2. 编写组件的结构:在loading.wxml文件中,可以使用合适的标签和样式来构建想要的载入动画效果,例如可以使用一个旋转的loading图标或者是一个逐帧动画来展示载入过程。 3. 定义组件的样式:在loading.wxss文件中,可以编写组件的样式代码,为载入动画提供合适的样式,包括大小、颜色、位置等,并通过class或id来选择组件的样式。 4. 在页面中引用组件:在需要显示载入动画的页面中,引入刚刚创建的loading组件,在页面的json文件中配置该组件的路径以及需要传递给组件的数据。 5. 设置组件的显示和隐藏:在页面的js文件中,通过设置数据来控制loading组件的显示和隐藏状态。可以通过设置组件的data中的某个属性为true或者false来控制组件的显示和隐藏。 6. 调用组件:在需要进行数据加载的时候,通过调用loading组件的显示方法来显示载入动画,例如在数据请求的开始和结束的地方分别调用。 通过上述步骤,就可以自定义微信小程序的loading组件显示载入动画方法。可以根据实际需求和设计要求来创建和设计组件的结构和样式,并通过设置组件的显示和隐藏状态来控制显示载入动画的时机。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狮子挽歌TT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值