小程序实现树形菜单以及折叠效果

实现原理:利用自定义组件递归使用,也就是自定义组件自引用

因为树状图的数据是从后台获取的,没有办法知道具体层级,但是他们的结构都是相同的,所以在自定义的组件中再去引用自身来实现需求

1.先写好树形菜单的样式结构,可以自定义假数据,将静态写好

2.自定义components,将写好的样式结构丢进去,子元素重复的结构就不需要了

3.父组件传递数据,自定义组件进行操作

可以去官网看看组件使用:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/

自定义组件:

<!-- wxml中的结构 -->

<view class='ul re'>
  <view class='li li{{item.id}}' wx:if="{{treedata.length>0}}" wx:for="{{treedata}}" wx:key="{{item.id}}">
    <view class='dai bb'>
        <!-- 如果没有子级不需要显示+ -符号 ,默认显示加号,即id和pid是不等的-->
      <view class='plus' bindtap='toggle' data-id='{{item.id}}' data-pid='{{item.pid}}' wx:if="{{item.children!=undefined&&item.children!=null&&item.children.length>0}}">{{item.id!=item.pid?'+':'-'}}</view>
    </view>
    <view class='span span{{item.id}} re' data-id="{{item.id}}" bindtap='myInfo' style="background-color:{{item.deathtime==null?'':'#9f9f9f'}}">
      <view class='name'>{{item.name}}</view>
      <view class='texts bb' wx:if='{{item.deathtime!=null}}'>故</view>
    </view>
    <!-- wx:if 如果没有子级就不需要去渲染了   hidden是用来后面做折叠操作的 -->
    <view class='ul' data-id='{{item.id}}' data-pid='{{item.pid}}' wx:if="{{item.children!=undefined&&item.children!=null&&item.children.length>0}}" hidden="{{item.id==item.pid}}">
      <servant treedata="{{item.children}}"></servant>
    </view>
  </view>
</view>
.ul {
  padding-left: 66rpx;
  position: relative;
}

.li {
  list-style-type: none;
  margin: 0;
  padding: 15rpx 100rpx 0;
  position: relative;
}

.li::before, .li::after {
  content: '';
  left: -40rpx;
  position: absolute;
  right: auto;
}

.li::before {
  border-left: 1rpx solid #999;
  bottom: 100rpx;
  height: 100%;
  top: 0;
  width: 2rpx;
}

.li::after {
  border-top: 1rpx solid #999;
  height: 40rpx;
  top: 50rpx;
  width: 140rpx;
}

.li .span {
  width: 153rpx;
  height: 66rpx;
  text-align: center;
  line-height: 66rpx;
  border: 1rpx solid #999;
  border-radius: 35rpx;
  display: inline-block;
  padding: 6rpx 16rpx;
  text-decoration: none;
  font-size: 32rpx;
  position: relative;
}

.ul>.li1::before, .ul>.li1::after {
  border-top: 1rpx solid #999;
  height: 40rpx;
  top: 50rpx;
  width: 140rpx;
  border-left: 0;
}

.li:last-child::before {
  height: 52rpx;
}

.texts {
  width: 45rpx;
  height: 45rpx;
  line-height: 45rpx;
  position: absolute;
  right: -8%;
  top: -28%;
  border-radius: 50%;
  background-color: #afafaf;
  font-size: 27rpx;
  color: #fff;
}

.dai {
  position: absolute;
  font-size: 27rpx;
  left: -15rpx;
  top: 34rpx;
  background-color: #fff;
  z-index: 999;
  padding: 0 6rpx;
  display: flex;
  align-items: center;
}

.plus {
  width: 40rpx;
  height: 40rpx;
  line-height: 40rpx;
  text-align: center;
  border-radius: 50%;
  background-color: #5c5c5c;
}
//在组件json文件中,需要声明component为true;组件中自引用需要声明usingComponents
{
    "component":true,
    "usingComponents":{
        "servant":"/components/treeMenu/treeMenu"    // 组件路径
    }
}
// 组件的js文件
// 组件的属性值和内部数据将被用于组件 wxml 的渲染,其中,属性值是可由组件外部传入的
Component({
  // 组件的属性列表
  properties: {
    // 定义属性,属性值可以在组件使用时指定
    treedata: {
      type: Array,
      value: []
    }
  },
  // 组件内的初始数据
  data: {
    mid: '', //  存储原来的pid
  },
  // 组件的方法列表
  methods: {
    //实现折叠效果 同时改变页面'+' '-'符号显示,返回的数据中每一项的id和pid是不等的
    toggle: function(e) {
      var id = e.currentTarget.dataset.id; //原来的id
      var pid = e.currentTarget.dataset.pid; //原来的pid
      if (!this.data.mid) {
        this.setData({
          mid: pid
        })
      }
      for (var i in this.properties.treedata) {
        if (this.properties.treedata[i].id == id) {

          if (this.properties.treedata[i].id == pid) {
            this.setData({
              [`treedata[${i}].pid`]: this.data.mid,    // es6模板语法
            })
          } else {
            this.setData({
              [`treedata[${i}].pid`]: id,
            })
          }
        }
      }
    }
  },

  // 组件所在页面的生命周期函数
  ready: function() {
   
  }

})

组件定义完成后,在其他页面中使用:

// 1. 页面json文件中需要声明

{
    "usingComponents":{
        "servant":"/components/treeMenu/treeMenu"    //自定义组件路径
    }
}


// 2. 页面js中定义数据(根据需求做请求操作)

Page({
    data:{
        treedata:[]
    }
})


// 3. 组件传值  通过组件定义的treedata进行数据传递,组件接收存储使用其渲染

<view>
    // 组件的属性treedata接收页面传递的数据
    <servant treedata='{{treedata}}'></servant>
</view>

效果图:

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值