问题描述
背景:实现教务小程序的一个空教室查询的展示面板。
环境:Taro小程序+React+TaroUI
实现目标:卡片式手风琴,移步文章末尾查看效果图。只注重功能,界面待完善
问题:
- 手风琴卡片的实现
- 根据传参,决定添加卡片的数量
- 默认情况下,针对手风琴的展开和闭合状态,是一开全开,一闭全闭。
1. 手风琴卡片的实现
第一步:将手风琴的AtAccordion套入AtCard;
第二步:在手风琴的AtList下套AtCard。
<AtCard>
<AtAccordion
open={this.state.open}
onClick={this.handleClick.bind(this)}
title='标题一'
>
<AtList hasBorder={false}>
<AtCard
note='小Tips'
extra='额外信息'
title='这是个标题'
thumb='http://www.logoquan.com/upload/list/20180421/logoquan15259400209.PNG'
>
这也是内容区 可以随意定义功能
</AtCard>
<AtCard
note='小Tips'
extra='额外信息'
title='这是个标题'
thumb='http://www.logoquan.com/upload/list/20180421/logoquan15259400209.PNG'
>
这也是内容区 可以随意定义功能
</AtCard>
</AtList>
</AtAccordion>
</AtCard>
2. 动态决定卡片个数
这一步前前后后做了很多更改,就不再赘述中间错误的尝试过程。
2.1 原始数据的处理
原始数据如下,在json里不能直观的获取key,json也难以实现遍历,所以我们对其修改
{
//[教室,教室容量]
"A6": [
[201, 30]
[202, 30]
[206, 60]
],
"A5":[
[301, 30]
[302, 30]
[306, 60]
] }
修改后我们可以通过key来索引value,通过map就可快速的遍历
[
{
"build": "A1",
"classrooms": [["19", "40"], ["183", "80"], ["145", "120"]],
},
{
"build": "A2",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
},
{
"build": "A3",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
},
{
"build": "A4",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
},
{
"build": "A5",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
}
]
2.2 二重map遍历实现动态添加组件
这里注意到map的参数是带下划线的,不带下划线不能用,虽然解决了但不太清楚为什么
<View>
{
this.state.classes.map((build, index) => {
return (
<View>
<AtCard>
<AtAccordion
open={this.state.open[index]}
onClick={(value)=>this.state.open=value}
// onClick={this.handleClick.bind(this, index)}
title={build["build"]}><AtList hasBorder={false}>
{
build["classrooms"].map((_classroom) => {
return (
<AtCard
note={'教室' + _classroom[0]}
extra={'教室容量:' + _classroom[1] + '人'}
title={_classroom[0]}
thumb='http://www.logoquan.com/upload/list/20180421/logoquan15259400209.PNG'
></AtCard>)
}
)
}
</AtList>
</AtAccordion>
</AtCard>
</View>)
})
}
</View>
3.手风琴单独展开闭合问题
参考@黑夜d星辰大佬的博客,实现了组件单独展开。但是又存在新的问题:只能单独展开一个。
原因:通过对所有open状态进行更新,目标open设为组件传过来的value,非目标更新为关闭。
解决办法:拷贝原有open,对原有open 进行更改。
handleClick(id, value) {
let open_T = this.state.open;
for (let i = 0; i < this.state.buildingNum; i++) {
if (i === id) {
open_T[i] = value
}
}
this.setState({
open: open_T
})
}
4.完整源码
import { AtAccordion, AtList, AtListItem, AtCard } from 'taro-ui'
import Taro from '@tarojs/taro'
import React, { Component } from 'react'
import { View, Image, Text } from '@tarojs/components'
import EmptyImg from '../../../assets/img/empty.svg'
export default class Index extends Component {
constructor(props) {
super(props)
this.state = {
open: [],
classes: [],
buildingNum: '',
}
}
componentWillMount() {
Taro.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: "#3374ff",
fail: (err) => {
console.log(err)
}
})
}
componentDidMount() {
var classes = [
{
"build": "A1",
"classrooms": [["19", "40"], ["183", "80"], ["145", "120"]],
},
{
"build": "A2",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
},
{
"build": "A3",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
},
{
"build": "A4",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
},
{
"build": "A5",
"classrooms": [["319", "80"], ["483", "30"], ["5545", "120"]],
}
]
this.setState({
classes: classes,
buildingNum: classes.length,
})
}
handleClick(id, value) {
let open_T = this.state.open;
for (let i = 0; i < this.state.buildingNum; i++) {
if (i === id) {
open_T[i] = value
}
}
this.setState({
open: open_T
})
}
render() {
return (
<View>
{this.state.classes === 0 ?
<View className='grade-none'>
<Image
src={EmptyImg}
className='grade-none-noneImg'
/>
<Text className='grade-none-noneText'>没有查询到空教室~</Text>
<View className='grade-none-ad'></View>
</View>
:
<View>
{
this.state.classes.map((build, index) => {
return (
<View>
<AtCard>
<AtAccordion
open={this.state.open[index]}
onClick={this.handleClick.bind(this, index)}
title={build["build"]}><AtList hasBorder={false}>
{
build["classrooms"].map((_classroom) => {
return (
<AtCard
note={'教室' + _classroom[0]}
extra={'教室容量:' + _classroom[1] + '人'}
title={_classroom[0]}
thumb='http://www.logoquan.com/upload/list/20180421/logoquan15259400209.PNG'
></AtCard>)
}
)
}
</AtList>
</AtAccordion>
</AtCard>
</View>)
})
}
</View>}
</View >
)
}
}
5.界面效果
6. 待解决问题
这种实现是通过对全部组件开闭状态进行更新实现的。很明显,效率很低,有没有效率高的解决办法,欢迎留言交流。