小程序实现手风琴列表功能

小程序实现手风琴列表功能

今天在开发过程中, 有一个功能是 手风琴列表, 考虑到产品的想法总是天马行空, 于是打算自己来做这个功能, 经过一上午的删删改改, 终于做出了一个自己认为还算达标的 手风琴列表 功能, 请看图!

在这里插入图片描述

在实现 折叠效果的时候, 第一时间想到的通过设置 height: auto 在实现 折叠效果, 然后发现设置 height: auto 会导致设置过渡时间不会起效果, 于是想到了动态获取 元素高度, 然后设置 transition: height .3s, 就可以完美的拥有 折叠效果 了, 所有代码如下

collapse.wxml (Component文件)


<view class="collapse">
    <view class="collapse-box custom-collapse"
          catch:tap="switchCollapseList" 
          data-index="{{index}}">
      <view class="title custom-title">{{title}}</view>
      <view wx:if="{{customRightIcon}}"
            class="{{index == actionIndex ? 'routerIcon' : 'resetIcon'}}">
        <slot name="right-icon"></slot>
      </view>
      <block wx:else>
        <image src="{{rightIcon}}" 
               class="rightIcon {{index == actionIndex ? 'routerIcon' : 'resetIcon'}}"></image>
      </block>
    </view>

    <view class="collapse-content"
          style="height: {{index == actionIndex ? collapseItemHeihgt : '0'}}px">
      <view class="collapse-item-class">
        <slot name="collapse-item"></slot>
      </view>
    </view>
</view>

collapse.wxss (Component文件)


.collapse-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  width: 100%;
  padding: 30rpx 32rpx;
  overflow: hidden;
  background-color: #fff;
  border-bottom: 1px solid #ebedf0;
}

.title{
  color: #323233;
  font-size: 28rpx;
  line-height: 24rpx;
}

.rightIcon{
  width: 32rpx;
  height: 30rpx;

}

.collapse-content {
  height:0px;
  overflow:hidden;
  transition:height .3s;  
  background-color: #fff;

}


.collapse-content > view{
  padding: 24rpx 32rpx;
  color: #525252;
  font-size: 28rpx;
  line-height: 1.5;
  background-color: #fff;
}


/* 将右侧 icon 进行旋转 */
.routerIcon{
  transition: all .3s;
  transform: rotate(180deg) !important;
}

/* 将右侧 icon 旋转重置 */
.resetIcon{
  transform: rotate(0deg);
  transition: all .3s;
}

collapse.js (Component文件)


Component({
  // 可通过外部传入 "collapse-item-class" 改变手风琴列表内容的默认样式
  // 可通过外部传入 "custom-collapse" 手风琴列表的默认样式
  // 可通过外部传入 "custom-title" 改变标题默认样式
  externalClasses: ['collapse-item-class', 'custom-collapse', 'custom-title'],

  // 开启插槽功能
  options: {
    multipleSlots: true
  },

  /**
   * 组件的属性列表
   */
  properties: {
    // 标题
    title: {
      type: String,
      observer(val) {
        console.log(val, '标题')
      }
    },
    // 索引
    index: {
      type: [Number, String]
    },
    // 选中索引
    actionIndex: {
      type: [Number, String],
      value: -1,
      observer(newVal) {
        if (newVal > -1) {
          // 计算手风琴高度
          this.calculationCollapseHeight()
        }

      }
    },
    // 右侧icon
    rightIcon: {
      type: String,
      value: '/image/default-bottom-arrow.png'
    },
    // 自定义右侧icon
    customRightIcon: {
      type: Boolean
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    collapseItemHeihgt: 0
  },

  /**
   * 组件的方法列表
   */
  methods: {
    /**
     * 计算手风琴内容高度
     */
    calculationCollapseHeight() {
      return new Promise((resolve) => {
        let self = this;
        let query = wx.createSelectorQuery().in(this)
        query.select('.collapse-item-class').boundingClientRect()
        query.exec(function (res) {
          self.setData({
            collapseItemHeihgt: res[0].height
          })
          resolve();
        })
      })
    },

    /**
     * 点击手风琴列表
     */
    switchCollapseList(e) {
      console.log(e, '---e')
      let self = this;
      let {
        index
      } = e.currentTarget.dataset;
      let actionIndex = self.data.actionIndex;

      // 判断当前点击手风琴列表是否为展开状态
      if (actionIndex == index) {
        self.setData({
          actionIndex: -1
        })
      } else {
        self.triggerEvent('switchCollapseItem', {
          index
        })
      }
    },
  }
})

index.wxml (Page文件)


<view class="tips-view">1、普通用法</view>
<v-collapse title="标题一" 
            index="1"
            actionIndex="{{oneActionIndex}}"
            bind:switchCollapseItem="oneSwiteFun">
  <view slot="collapse-item">今天天气真好, 适合摸鱼</view>
</v-collapse>
<v-collapse title="标题二" 
            index="2"
            actionIndex="{{oneActionIndex}}"
            bind:switchCollapseItem="oneSwiteFun">
  <view slot="collapse-item">今天天气真好, 适合摸鱼</view>
</v-collapse>
<v-collapse title="标题三" 
            index="3"
            actionIndex="{{oneActionIndex}}"
            bind:switchCollapseItem="oneSwiteFun">
  <view slot="collapse-item">今天天气真好, 适合摸鱼</view>
</v-collapse>



<view class="tips-view">2、自定义内容样式</view>
<block wx:for="{{collapseList}}"
       wx:key="index">
  <v-collapse title="{{item.title}}" 
              index="{{index}}"
              actionIndex="{{twoActionIndex}}"
              collapse-item-class="item-class"
              bind:switchCollapseItem="twoSwiteFun">
    <view slot="collapse-item">{{item.content}}</view>
  </v-collapse>
</block>



<view class="tips-view">3、自定义内容样式 and 自定义右侧icon</view>
<block wx:for="{{collapseList}}"
       wx:key="index">
  <v-collapse title="{{item.title}}" 
              index="{{index}}"
              actionIndex="{{threeActionIndex}}"
              collapse-item-class="item-class"
              customRightIcon="true"
              bind:switchCollapseItem="threeSwiteFun">
    <image slot="right-icon"
           src="/image/bottom-arrow.png"
           class="right-icon"></image>
    <view slot="collapse-item">{{item.content}}</view>
  </v-collapse>
</block>

index.wxss (Page文件)


page{
  height: 100%;
  background: rgb(247, 248, 250)
}

.tips-view{
  margin-left: 20rpx;
  margin-top: 40rpx;
}

.item-class{
  color: red !important;
}

.right-icon{
  width: 40rpx;
  height: 40rpx;
}

index.js (Page文件)


Page({

  /**
   * 页面的初始数据
   */
  data: {
    collapseStatus: false,
    // 普通用法
    oneActionIndex: -1,
    // 自定义内容样式
    twoActionIndex: -1,
    // 自定义内容样式 and 自定义右侧icon
    threeActionIndex: -1,
    collapseList: [{
      title: '标题一',
      content: '最灵繁的人也看不见自己的背脊。'
    }, {
      title: '标题二',
      content: '业余生活要有意义,不要越轨。'
    }, {
      title: '标题三',
      content: '希望的灯一旦熄灭,生活刹那间变成了一片黑暗。'
    }],
  },
  
  oneSwiteFun(e) {
    console.log(e, '--e')
    let {
      index
    } = e.detail
    this.setData({
      oneActionIndex: index
    })
  },

  twoSwiteFun(e){
    console.log(e, '--e')
    let {
      index
    } = e.detail
    this.setData({
      twoActionIndex: index
    })
  },

  threeSwiteFun(e){
    console.log(e, '--e')
    let {
      index
    } = e.detail
    this.setData({
      threeActionIndex: index
    })
  }
})

最后不要忘记在 json 文件引入组件, 要不然不会起效果的

index.json (Page文件)

 
 {
   "usingComponents": {
     "v-collapse": "/components/02-collapse/02-collapse"
   }
 }

欢迎大家来提出更好的方案

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值