必要: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パッケージとしてデプロイされることが多い。
序文バックエンド開発では、一度に大量のデータがロードされ、メモリやディスク IO のオーバーヘッドが...
Web ページ ボックス モデルには 2 種類あります。 1: 標準 W3C ボックス モデル。2:...
目次サーバーはjupyterノートブックを実行します仮想環境次にファイアウォールをオフにしますJup...
目次序文1. Linux は yum ソースを変更します (MYSQL のインストールが遅い場合は試...
結合の種類1. 内部結合: 結合関係を持つ 2 つのテーブル内のフィールドは、結合関係を満たすレコー...
ホスト 'xxxx' はこの MySQL サーバーに接続できませんエラー: 1130...
本日、ローカル開発環境で突然「入力ファイルが指定されていません」というエラーが発生してしまいました。...
1. 従来のLRUリンクリストについて簡単に説明するLRU:最も最近使われなかったものLRU リンク...
目次序文1. 少ない2. コンポーネントをインポートする3. 設定ファイルを変更するステップ1: l...
背景インデックスは諸刃の剣です。クエリ速度は向上しますが、DML 操作も遅くなります。結局のところ、...
シナリオ会社のプロジェクトはDockerでデプロイされています。原因不明ですが、コンテナが時々停止し...
Firefox は、多くの拡張機能とプラグインを備えた、よく使用されるブラウザです。IE に比べて多...
序文mysqlslap は、MySQL サーバーへのクライアント負荷をシミュレートし、各ステージの時...
前回は、Explain 実行プランの表示、インデックスの分析など、MySQL での SQL クエリの...
vscode エディタを使用して vue テンプレートを作成すると、新しい vue ファイルを作成す...