위 챗 애플 릿 은 고정 헤더,목록 격자 구성 요 소 를 실현 합 니 다.
위 챗 애플 릿 은 고정 표 헤드 고정 열 표 구성 요 소 를 실현 합 니 다.
기능 점
사고의 방향 을 실현 하 다.
처음에 세 개의 ScrollView 로 스크롤 연결 을 실현 하려 고 했 습 니 다.표 의 머리,열 을 고정 시 키 려 면 표 의 내용 이 표 의 머리,열 을 굴 리 는 것 도 스크롤 에 대응 해 야 합 니 다.demo 를 쓴 후에 하나의 ScrollView 의 위치 정 보 를 감청 하여 다른 두 개의 ScrollView 의 위 치 를 설정 하 는 것 이 매우 느 리 고 체험 이 매우 좋 지 않 습 니 다.
position:sticky 사용 하기;표 의 맨 위 에 있 는 sticky 와 표 의 첫 번 째 요 소 를 현재 줄 왼쪽 에 있 는 sticky 와 비교 합 니 다.
질문
구체 적 인 코드(react\taro 3.0)
index.tsx
/**
* 、 、
* @example <Table data={data} dataAttribute={dataAttribute} sortTypeChange={sortTypeChange} handleRow={toDetails}/>
*/
import React, { useState, useMemo, useEffect } from 'react'
import classNames from 'classnames'
// components
import { View, Text, ScrollView } from '@tarojs/components'
// utils
import { noop } from '@/utils/util'
// styles
import styles from './index.module.less'
interface DataAttributeItem {
title: string
key: string | number
sortKey?: string | number
}
interface Props {
data: Array<any>
dataAttribute: Array<DataAttributeItem>
sortTypeChange?: (sort_item_id: any, sort_desc: boolean) => void
handleRow?: (data: any) => void
handleScrollToLower?: (e: any) => void
}
export default function Table(props: Props) {
const { data, dataAttribute, sortTypeChange = noop, handleRow = noop, handleScrollToLower = noop } = props
const [isSortDesc, setIsSortDesc] = useState<boolean>(true)
const [sortIndex, setSortIndex] = useState<number>(1)
const tableWidth = useMemo(() => {
return `${(dataAttribute.length * 148 + 48)}rpx`
}, [dataAttribute])
const tableHeight = useMemo(() => {
return `${((data.length + 1) * 96)}rpx`
}, [data])
const handleSortItem = (attrItem, attrIndex) => {
if (attrIndex === 0) {
return
}
const beforeIndex = sortIndex
const sortKey = attrItem.sortKey
dataAttribute.map((item, index)=>{
if (item.sortKey === sortKey) {
if (beforeIndex === index) {
setIsSortDesc(!isSortDesc)
} else {
setSortIndex(index)
setIsSortDesc(true)
}
}
})
}
useEffect(()=>{
const sort_desc = isSortDesc
const sort_item_id = dataAttribute[sortIndex].sortKey
sortTypeChange(sort_item_id,sort_desc)
},[sortIndex, isSortDesc])
return (
<ScrollView className={styles['table']} scrollY scrollX onScrollToLower={handleScrollToLower}>
<View className={styles['sticky-box']} style={{height: tableHeight}}>
<View className={styles['grey-box']} style={{width: tableWidth, position: 'sticky'}}/>
<View className={styles['table__head']} style={{width: tableWidth, position: 'sticky'}}>
{dataAttribute.map((attrItem, attrIndex) => (
<View className={styles['table__head__td']} key={attrIndex} onClick={()=>handleSortItem(attrItem, attrIndex)}>
<Text
className={classNames({
[styles['table__head__td__text']]: true,
[styles['table__head__td__text-active']]: sortIndex === attrIndex,
})}
key={attrIndex}
>{attrItem.title}</Text>
{attrIndex !== 0 && <View
className={classNames({
[styles['table__head__td__sorter-indicate']]: true,
[styles['table__head__td__sorter-indicate--asc-active']]: sortIndex === attrIndex && !isSortDesc,
[styles['table__head__td__sorter-indicate--desc-active']]: sortIndex === attrIndex && isSortDesc
})}
/>}
</View>
))}
</View>
{data.map((dataItem, dataIndex) => (
<View className={styles['table__row']} key={dataIndex} style={{width: tableWidth}} onClick={() => handleRow(dataItem)}>
{dataAttribute.map((attrItem, attrIndex) => {
return (
<Text className={styles['table__row__td']} key={attrIndex}>{dataItem[attrItem.key] || '-'}</Text>
)
})}
</View>
))}
</View>
</ScrollView>
)
}
index.module.less
@import '~@/assets/style/mixins/ellipsis.less';
page{
font-size: 26rpx;
line-height: 60rpx;
color: #222;
height: 100%;
width: 100%;
}
.grey-box{
height: 10rpx;
top: 0;
background: #f8f8f8;
z-index: 100;
}
.table{
position: relative;
overflow: scroll;
width: 100%;
height: 100%;
overflow: scroll;
&__head{
position: relative;
height: 96rpx;
white-space: nowrap;
// position: sticky;
top: 10rpx;
z-index: 100;
height: 88rpx;
font-size: 24rpx;
line-height: 88rpx;
color: #aaabbd;
background-color: #f8f8f8;
border-bottom: 2rpx solid #ecf1f8;
background-color: #fff;
white-space: nowrap;
display: flex;
&__td{
.ellipsis();
width: 148rpx;
// padding-right: 40rpx;
display: flex;
justify-content: flex-start;
align-items: center;
background-color: #fff;
position: relative;
box-sizing: border-box;
&:nth-child(1) {
padding-left: 24rpx;
width: 154rpx;
margin-right: 40rpx;
position: sticky;
z-index: 10;
left: 0;
}
&__text{
display: inline;
&-active{
color: #6d70ff;
}
}
&__sorter-indicate{
width: 24rpx;
height: 24rpx;
display: inline-block;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url('https://icon1.png');
&--asc-active {
background-image: url('https://icon2.png');
}
&--desc-active {
background-image: url('https://icon3.png');
}
}
}
}
&__row{
position: relative;
height: 96rpx;
white-space: nowrap;
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom: 2rpx solid #ecf1f8;
&__td{
// .ellipsis();
overflow: scroll;
white-space: nowrap;
width: 148rpx;
// padding-right: 40rpx;
display: inline-block;
background-color: #fff;
position: relative;
box-sizing: border-box;
font-size: 26rpx;
line-height: 96rpx;
&:nth-child(1) {
margin-right: 40rpx;
padding-left: 24rpx;
width: 154rpx;
position: sticky;
z-index: 10;
left: 0;
}
}
}
}
구체 적 인 코드(애플 릿 원생)
<ScrollView class="table" scroll-x scroll-y bindscrolltolower="handleScrollToLower">
<View class="sticky-box" style="height:{{tableHeight}}rpx;">
<View class="table__head" style="width:{{tableWidth}}rpx;">
<View class="table__head__td" wx:for="{{dataAttribute}}" wx:key="attrIndex" wx:for-index="attrIndex" wx:for-item="attrItem">
<Text
class="table__head__td__text"
>{{attrItem.title}}</Text>
</View>
</View>
<View class="table__row" wx:for="{{data}}" wx:key="dataIndex" wx:for-index="dataIndex" wx:for-item="dataItem" style="width:{{tableWidth}}rpx;">
<Text class="table__row__td" wx:for="{{dataAttribute}}" wx:key="dataIndex" wx:for-index="attrIndex" wx:for-item="attrItem">{{dataItem[attrItem.key] || '-'}}</Text>
</View>
</View>
</ScrollView>
const app = getApp()
Page({
data: {
data: [
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
{
a: 123,
b: 456,
c: 489,
d: 789,
e: 458,
f: 789
},
],
dataAttribute: [
{
title: ' ',
key: 'a'
},
{
title: ' 2 ',
key: 'b'
},
{
title: ' 3 ',
key: 'c'
},
{
title: ' 4 ',
key: 'd'
},
{
title: ' 5 ',
key: 'e'
},
{
title: ' 6 ',
key: 'f'
}
],
tableHeight: (20 + 1) * 96,
tableWidth: 200 * 6 + 60
}
})
page{
font-size: 26rpx;
line-height: 60rpx;
color: #222;
height: 100%;
width: 100%;
}
.table{
display: block;
position: relative;
overflow: scroll;
width: 100%;
height: 100%;
}
.sticky-box{
}
.table__head{
height: 96rpx;
white-space: nowrap;
position: sticky;
top: 0rpx;
z-index: 100;
height: 88rpx;
font-size: 24rpx;
line-height: 88rpx;
color: #aaabbd;
background-color: #f8f8f8;
border-bottom: 2rpx solid #ecf1f8;
background-color: #fff;
white-space: nowrap;
display: flex;
}
.table__head__td{
width: 200rpx;
display: flex;
justify-content: flex-start;
align-items: center;
background-color: #fff;
box-sizing: border-box;
position: relative;
overflow: hidden;
white-space: nowrap;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
}
.table__head__td:nth-child(1) {
padding-left: 24rpx;
width: 260rpx;
margin-right: 40rpx;
position: sticky;
z-index: 101;
left: 0rpx;
}
.table__head__td__text{
display: inline;
}
.table__row{
position: relative;
height: 96rpx;
white-space: nowrap;
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom: 2rpx solid #ecf1f8;
}
.table__row__td{
overflow: scroll;
white-space: nowrap;
width: 200rpx;
display: inline-block;
background-color: #fff;
box-sizing: border-box;
font-size: 26rpx;
line-height: 96rpx;
position: relative;
overflow: hidden;
white-space: nowrap;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
}
.table__row__td:nth-child(1) {
margin-right: 40rpx;
padding-left: 24rpx;
width: 260rpx;
position: sticky;
z-index: 10;
left: 0;
}
총결산위 챗 애플 릿 이 고정 헤더,목록 격자 구성 요 소 를 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 위 챗 애플 릿 고정 헤더 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
OpenSSL 생 성 ssl 인증서텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.