小程序实现手风琴列表功能
今天在开发过程中, 有一个功能是 手风琴列表
, 考虑到产品的想法总是天马行空, 于是打算自己来做这个功能, 经过一上午的删删改改, 终于做出了一个自己认为还算达标的 手风琴列表
功能, 请看图!
在实现 折叠效果
的时候, 第一时间想到的通过设置 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"
}
}
欢迎大家来提出更好的方案