必要:WeChatアプレットは固定ヘッダーと固定列のテーブルコンポーネントを実装します(若干の変更を加えることでモバイル端末にも適用可能) 機能ポイント
レンダリング実装のアイデアスクロールの連動を実装するために、3 つの ScrollView を使用することを考え始めました。ヘッダーと列が固定されている場合、テーブルの内容がスクロールすると、ヘッダーと列もそれに応じてスクロールする必要があります。デモを作成した後、1 つの ScrollView の位置情報を監視して他の 2 つの ScrollView の位置を設定するのは非常に面倒で、エクスペリエンスが非常に悪いことがわかりました。position:sticky; を使用して、ヘッダーをテーブルの上部に固定し、各行の最初の要素を現在の行の左側に固定します。 発生した問題:
具体的なコード(react\taro3.0)インデックス.tsx /** * スライド可能、固定ヘッダー、固定列のテーブル コンポーネント* @example <Table data={data} dataAttribute={dataAttribute} sortTypeChange={sortTypeChange} handleRow={toDetails}/> */ 'react' から React、{useState、useMemo、useEffect} をインポートします。 'classnames' から classNames をインポートします // コンポーネント '@tarojs/components' から { View, Text, ScrollView } をインポートします。 // ユーティリティ '@/utils/util' から { noop } をインポートします // スタイル './index.module.less' からスタイルをインポートします インターフェース DataAttributeItem { タイトル: 文字列 キー: 文字列 | 数値 ソートキー?: 文字列 | 数値 } インターフェースProps{ データ: 配列<任意> データ属性: 配列<データ属性項目> sortTypeChange?: (sort_item_id: 任意、sort_desc: ブール値) => void handleRow?: (データ: 任意) => void handleScrollToLower?: (e: 任意) => void } デフォルトの関数Table(props: Props)をエクスポートします。 const { data、dataAttribute、sortTypeChange = noop、handleRow = noop、handleScrollToLower = noop } = props const [isSortDesc, setIsSortDesc] = useState<boolean>(true) const [sortIndex, setSortIndex] = useState<数値>(1) const テーブル幅 = useMemo(() => { `${(dataAttribute.length * 148 + 48)}rpx` を返します }, [データ属性]) const テーブルの高さ = useMemo(() => { `${((data.length + 1) * 96)}rpx` を返します }、 [データ]) const ハンドルソートアイテム = (属性アイテム、属性インデックス) => { 属性インデックス === 0 の場合 { 戻る } 定数 beforeIndex = sortIndex 定数sortKey = attrItem.sortKey dataAttribute.map((item, index)=>{ if (item.sortKey === sortKey) { if (beforeIndex === インデックス) { setIsSortDesc(!isSortDesc) } それ以外 { setSortIndex(インデックス) 並べ替え順序を設定します(true) } } }) } 使用効果(()=>{ 定数 sort_desc = isSortDesc const sort_item_id = データ属性[ソートインデックス].sortKey ソートタイプ変更(ソート項目ID、ソート順序) },[ソートインデックス、isSortDesc]) 戻る ( <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)}> <テキスト クラス名={クラス名({ [スタイル['table__head__td__text']]: true, [styles['table__head__td__text-active']]: sortIndex === attrIndex、 })} キー={属性インデックス} >{attrItem.title}</テキスト> {attrIndex !== 0 && <ビュー クラス名={クラス名({ [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 })} }}} </表示> ))} </表示> {data.map((データ項目、データインデックス) => ( <View className={styles['table__row']} key={dataIndex} style={{width: tableWidth}} onClick={() => handleRow(dataItem)}> {dataAttribute.map((attrItem, attrIndex) => { 戻る ( <Text className={styles['table__row__td']} key={attrIndex}>{dataItem[attrItem.key] || '-'}</Text> ) })} </表示> ))} </表示> </スクロールビュー> ) } インデックスモジュール @import '~@/assets/style/mixins/ellipsis.less'; ページ{ フォントサイズ: 26rpx; 行の高さ: 60rpx; 色: #222; 高さ: 100%; 幅: 100%; } .grey-box{ 高さ: 10rpx; 上: 0; 背景: #f8f8f8; zインデックス: 100; } 。テーブル{ 位置: 相対的; オーバーフロー: スクロール; 幅: 100%; 高さ: 100%; オーバーフロー: スクロール; &__頭{ 位置: 相対的; 高さ: 96rpx; 空白: ラップなし; // 位置: スティッキー; 上: 10rpx; zインデックス: 100; 高さ: 88rpx; フォントサイズ: 24rpx; 行の高さ: 88rpx; 色: #aaabbd; 背景色: #f8f8f8; 下部境界線: 2rpx 実線 #ecf1f8; 背景色: #fff; 空白: ラップなし; ディスプレイ: フレックス; &__td{ .ellipsis(); 幅: 148rpx; // パディング右: 40rpx; ディスプレイ: フレックス; コンテンツの配置: flex-start; アイテムの位置を中央揃えにします。 背景色: #fff; 位置: 相対的; ボックスのサイズ: 境界線ボックス; &:n番目の子(1) { 左パディング: 24rpx; 幅: 154rpx; 右マージン: 40rpx; 位置: 固定; zインデックス: 10; 左: 0; } &__文章{ 表示: インライン; &-アクティブ{ 色: #6d70ff; } } &__sorter-indicate{ 幅: 24rpx; 高さ: 24rpx; 表示: インラインブロック; 背景繰り返し: 繰り返しなし; 背景サイズ: 100% 100%; 背景画像: url('https://icon1.png'); &--asc-アクティブ { 背景画像: url('https://icon2.png'); } &--desc-active { 背景画像: url('https://icon3.png'); } } } } &__行{ 位置: 相対的; 高さ: 96rpx; 空白: ラップなし; ディスプレイ: フレックス; コンテンツの配置: flex-start; アイテムの位置を中央揃えにします。 下部境界線: 2rpx 実線 #ecf1f8; &__td{ // .ellipsis(); オーバーフロー: スクロール; 空白: ラップなし; 幅: 148rpx; // パディング右: 40rpx; 表示: インラインブロック; 背景色: #fff; 位置: 相対的; ボックスのサイズ: 境界線ボックス; フォントサイズ: 26rpx; 行の高さ: 96rpx; &:n番目の子(1) { 右マージン: 40rpx; 左パディング: 24rpx; 幅: 154rpx; 位置: 固定; zインデックス: 10; 左: 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"> <テキスト クラス="table__head__td__text" >{{attrItem.title}}</テキスト> </表示> </表示> <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> </表示> </表示> </スクロールビュー> const アプリ = getApp() ページ({ データ: { データ: [ { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, { 123, b: 456, c: 489, d: 789, e: 458, 女性: 789 }, ]、 データ属性: [ { タイトル: 「最初の列」、 キー: 'a' }, { タイトル: '列2'、 キー: 'b' }, { タイトル: '列3'、 キー: 'c' }, { タイトル: 'コラム4'、 キー: 'd' }, { タイトル: 'コラム5'、 キー: 'e' }, { タイトル: 「コラム6」 キー: 'f' } ]、 テーブルの高さ: (20 + 1) * 96, テーブル幅: 200 * 6 + 60 } }) ページ{ フォントサイズ: 26rpx; 行の高さ: 60rpx; 色: #222; 高さ: 100%; 幅: 100%; } 。テーブル{ 表示: ブロック; 位置: 相対的; オーバーフロー: スクロール; 幅: 100%; 高さ: 100%; } .sticky-box{ } .table__head{ 高さ: 96rpx; 空白: ラップなし; 位置: 固定; 上: 0rpx; zインデックス: 100; 高さ: 88rpx; フォントサイズ: 24rpx; 行の高さ: 88rpx; 色: #aaabbd; 背景色: #f8f8f8; 下部境界線: 2rpx 実線 #ecf1f8; 背景色: #fff; 空白: ラップなし; ディスプレイ: フレックス; } .table__head__td{ 幅: 200rpx; ディスプレイ: フレックス; コンテンツの配置: flex-start; アイテムの位置を中央揃えにします。 背景色: #fff; ボックスのサイズ: 境界線ボックス; 位置: 相対的; オーバーフロー: 非表示; 空白: ラップなし; -o-テキストオーバーフロー:省略記号; テキストオーバーフロー: 省略記号; } .table__head__td:n番目の子(1) { 左パディング: 24rpx; 幅: 260rpx; 右マージン: 40rpx; 位置: 固定; zインデックス: 101; 左: 0rpx; } .table__head__td__text{ 表示: インライン; } .table__row{ 位置: 相対的; 高さ: 96rpx; 空白: ラップなし; ディスプレイ: フレックス; コンテンツの配置: flex-start; アイテムの位置を中央揃えにします。 下部境界線: 2rpx 実線 #ecf1f8; } .table__row__td{ オーバーフロー: スクロール; 空白: ラップなし; 幅: 200rpx; 表示: インラインブロック; 背景色: #fff; ボックスのサイズ: 境界線ボックス; フォントサイズ: 26rpx; 行の高さ: 96rpx; 位置: 相対的; オーバーフロー: 非表示; 空白: ラップなし; -o-テキストオーバーフロー:省略記号; テキストオーバーフロー: 省略記号; } .table__row__td:n番目の子(1) { 右マージン: 40rpx; 左パディング: 24rpx; 幅: 260rpx; 位置: 固定; zインデックス: 10; 左: 0; } 要約するWeChatミニプログラムで固定ヘッダーとテーブルコンポーネントを実装する方法に関するこの記事はこれで終わりです。WeChatミニプログラムの固定ヘッダーに関する関連コンテンツの詳細については、123WORDPRESS.COMで以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も123WORDPRESS.COMを応援してください。 |
<<: MySQLにおけるACIDトランザクションの実装原理の詳細な説明
>>: SSMプロジェクトは、ホットデプロイメント構成を実装するためにTomcatとMavenを使用してWARパッケージとしてデプロイされることが多い。
目次1. パーティクルエフェクト2. シーンを読み込む3. さまざまな粒子効果の実現エンディング: ...
目次1. MySQL msiバージョンをダウンロードする2. インストール3. 環境変数を設定する1...
この記事では、docker pull がリセットされる問題を解決する方法を紹介し、皆さんと共有します...
この記事では、HTTP プロトコルのリファラーのメタデータ パラメータの提案について説明します。この...
序文この実験では、デバッグ用に2つの仮想マシン(CentOs6とRed Hat 6)を準備します。 ...
1つ。 wget https://dev.mysql.com/get/mysql57-communi...
Apache Arrow は、BigQuery を含むさまざまなビッグデータ ツールで使用される一...
ssh は私が最も頻繁に使用する 2 つのコマンドライン ツールのうちの 1 つです (もう 1 つ...
VMwareaのインストールプロセスは説明しませんが、主にwin7イメージをロードする方法を説明しま...
簡単に言うと、ウェアハウスとして使用される仮想マシンの IP は 192.168.149.129 で...
データは貴重なものであることは誰もが知っています。データをバックアップしなければ、データをそのまま放...
JavaScript でポインターの位置を取得する方法は、イベント オブジェクトの pageX と ...
proxy_intercept_errors と recursive_error_pages を使...
Navicat は、データベースに接続するときにエラー 10060 および 1045 を報告します...
モバイル デバイス向けに開発する場合、Retina 画面上で要素の境界線が太くなるという問題に遭遇す...