react+taro小程式:手風琴式卡片的動態實現
阿新 • • 發佈:2021-01-21
目錄
問題描述
背景:實現教務小程式的一個空教室查詢的展示面板。
環境: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. 待解決問題
這種實現是通過對全部元件開閉狀態進行更新實現的。很明顯,效率很低,有沒有效率高的解決辦法,歡迎留言交流。