ホームページ  >  記事  >  ウェブフロントエンド  >  UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

青灯夜游
青灯夜游転載
2022-01-07 19:12:286286ブラウズ

この記事では、複雑なシナリオにおけるテーブル コンポーネント (UniApp) の実用的な実装である UniApp を紹介します。皆様のお役に立てれば幸いです。

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

#あなたは成熟したプログラマーであり、自分自身の車輪を再発明する方法を知る必要があります (uniApp プラグイン マーケットを検索しましたが、プラグインは見つかりませんでした)それは私のニーズを満たすものです。他に方法はありません。ホイールを自分で作るしかありません)。この記事はその記録を振り返ることを目的としています。
利用シナリオ: uniApp、モバイル端末 (ミニプログラム、アプリ、H5 対応)

ニーズに応じて特定の機能を整理:

ニーズに応じて整理

  • テーブル名

    • 設定可能な背景

    • フォント スタイルは変更可能 (サイズ、 color)

    • メニュー ボタン (外部露出イベントが必要)

  • ヘッダー

    • マルチレベルヘッダーのサポート

    • ##固定ヘッダー

    • ##ヘッダー行はカスタム名をサポート
    • ##テーブル
  • セル幅の設定をサポート

    • 最初の列を固定

    • サポートツリーデータ

    • コンテンツは画像とリンクをサポートします

    • その他
  • ソートの内部実装

    • ##ページングの内部実装

    • ##合計行の内部計算
    • #コンポーネント全体に関するいくつかの考え

関数は比較的複雑であり、それを 1 つのファイルに詰め込むのは洗練されておらず、煩雑になります。 -> を押す 大まかな方向性はいくつかのモジュールに分割されています (細かい粒度)

#多くの要件があり、直感的には渡す必要があるパラメーターが多数あります->モジュール定義、パラメータも分類されています

  • パラメータがたくさんありますが、それらをよりエレガントに管理し、開始の難しさを軽減するにはどうすればよいでしょうか? -> 設定ファイル

    config.js
  • を作成し、その中にデフォルト値を設定します。これは、
  • フィールドの説明

    デフォルトのステータス管理
  • ##の役割を果たします。
  • ##これにはいくつかのアイコンの使用が含まれます -> iconfontアイコン ライブラリを選択します

    技術的な実装の問題
  • 使用環境の制限による: uniApp は比較的単純なテーブル関連コンポーネントを実装しますが、非 H5 環境 (

    rowspan
  • など) では比較的大きな制限があります。 ,
colspan

は設定できません)、使い方も面倒でプロジェクトのニーズを満たせないように思えたので、最終的にホイールを自分で作成することにしました。

ヘッダー部分主な問題は、マルチレベルヘッダーの処理にあり、それをどのように実行するかに基づいています。データドライバーディスプレイに表示されます。当初は

html table

という形で実装する予定でしたが、開発中には多くの問題が発生しました。まず、データ処理が面倒で、行数と # を計算しなければなりませんでした。各行の ##colspan## 個のセル。#, rowspan。また、td、tr などのコンポーネントは存在しないため、自分で実装する必要があります。

columns のデータは以下のようにツリー状になっています <pre class="brush:js;toolbar:false;">columns = [ { &quot;title&quot;: &quot;区域&quot;, &quot;dataIndex&quot;: &quot;区域&quot; }, { &quot;title&quot;: &quot;广州一区&quot;, &quot;children&quot;: [ { &quot;title&quot;: &quot;销售&quot;, &quot;dataIndex&quot;: &quot;广州一区销售&quot;}, { &quot;title&quot;: &quot;计划销售&quot;, &quot;dataIndex&quot;: &quot;广州一区计划销售&quot; }, { &quot;title&quot;: &quot;达成&quot;, &quot;dataIndex&quot;: &quot;广州一区达成&quot;} ] }, // ... ]</pre> flex レイアウト を使えば実現できるようです各グリッドは垂直に中央に設定され、children が存在する場合は、recursive rendering

をトラバースします。レンダリングは再帰的に呼び出す必要があるため、再帰部分はコンポーネントに分離されます:

titleColumn## #。まずコードを投稿します (コードはコミュニティにリリースされています。興味がある場合は、Portal をチェックしてください):

table-header.vue
titleColumn.vue


ここに穴があります

:

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発通常の

vue

では再帰コンポーネントを導入する必要はありませんが、uniApp では再帰コンポーネントが必要です。

// titleColumn.vue
import titleColumn from "./title-column.vue"

文体が拡張されておらず、書きにくいです。効果を直接見てみましょう (とても良い気分です、笑): UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

#テーブルの内容

Here まず、columns

のデータを処理する必要があります (複数レベルのヘッダーの状況を考慮する必要があります)。上記の

columns

に従って、実際の列を取得します。

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

実際にレンダリングする必要がある列データを保存するために使用される新しい変数dataIndexsを作成します

#再帰処理columns最後のリーフノードを取得して保存します。 ############キーコード: ###

// 根据Column 获取body中实际渲染的列
fmtColumns(list) {
    // 保存叶子节点
    this.dataIndexs = []
    if (!list || !list.length) return
    // 获取实际行
    this.columnsDeal(list)
},

// 
columnsDeal(list, level = 0) {
    list.forEach(item => {
        let { children, ...res } = item
        if (children && children.length) {
            this.columnsDeal(children, level + 1)
        } else {
            this.dataIndexs.push({ ...res })
        }
    })
},

接下来就是处理列表数据中的树形结构了。

先看看数据结构 tableData:

tableData = [
    {
		"key": 1,
		"区域": "广州",
		"销售": 100,
		"计划销售": 200,
		"达成": "50.0%",
		"达成排名": 1,
		"GroupIndex": 1,
		"GroupLayer": 1,
		"GroupKey": "广州",
		"children": [{
				"key": 11,
				"区域": "广州一区",
				"小区": "广州一区",
				"销售": 60,
				"计划销售": 120,
				"达成": "50.0%",
				"达成排名": 1,
				children: [{
					"key": 111,
					"区域": "广州一区1",
					"小区": "广州一区1",
					"销售": 60,
					"计划销售": 120,
					"达成": "50.0%",
					"达成排名": 1,
				}]
			},
			{ "key": 12, "区域": "广州二区", "小区": "广州二区", "销售": 40, "计划销售": 80, "达成": "50.0%", "达成排名": 1 },
		],
	},
]

树形的结构,key是唯一值。

有想过使用递归组件的方式实现,但是考虑到会涉及到展开、收起的操作。也是比较麻烦。

最终的方案是把数据扁平化处理,为每条数据添加 层级、是否子数据、父级ID 等属性。并通过一个数组变量来记录展开的行,并以此控制子数据的显示与否。处理后的数据存放在 dataList

扁平化处理函数:

// 递归处理数据,tree => Array
listFmt(list, level, parentIds = []) {
    return list.reduce((ls, item) => {
        let { children, ...res } = item
        // 错误提示
        if (res[this.idKey] === undefined || !res[this.idKey] === null) {
            // console.error(`tableData 数据中存在 [idKey] 属性不存在数据,请检查`)
        }
        let nowItem = {
            ...res,
            level,
            hasChildren: children && children.length,
            parentIds,
            children,
            [this.idKey]: res[this.idKey] && res[this.idKey].toString()
        }
        ls.push(nowItem)
        if (children && children.length) {
            this.isTree = true
            ls = ls.concat(this.listFmt(children, level + 1, [...parentIds, nowItem[this.idKey]]))
        }
        return ls
    }, [])
},

最终得到的数据如下:

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

数据处理完可以渲染了,

需要嵌套两层遍历:

第一层 遍历 dataList 得到行

第二层 遍历 dataIndexs 得到列

最终完成渲染:

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

固定首列,固定表头

使用css属性:position: sticky实现。粘性定位元素(stickily positioned element)。大家都是成熟的前端程序猿啦~~,就不具体介绍了。说说一些需要注意的细节:

兼容性

UniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発

uniapp中小程序模式、App模式是支持的!!!

限制

  • 设置了position:sticky之后必现指定top  left  right  bottom其中任一,才会生效。不设置的话表现和相对定位相同。topbottom 或者 leftright 同时设置的情况下,topleft的优先级高。

  • 设定为 position:sticky 元素的任意父节点的 overflow 属性必须是visible,否则 不会生效 (都不能滚动还能咋办)。

其他

造个轮子不难,造个好用的轮子不易。

涉及一些布局上和css部分的东西在文章中不好表达,不细说了,有兴趣的可以拉代码看看。传送门

开发过程中也遇到过不少的问题,都是一路修修补补过来,前期没有构思好会导致后面的开发磕磕碰碰(刚开始模块、参数没有划分好,整个东西逻辑都比较乱,后面停下来从新思考调整了,有种豁然开朗的痛快)

搬砖去了~

原文地址:https://juejin.cn/post/7083401121486045198

作者:沐夕花开

推荐:《uniapp教程

以上がUniApp 複雑なシナリオ向けのテーブル コンポーネントの実用的な開発の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。