ホームページ  >  記事  >  ウェブフロントエンド  >  Element UIテーブルコンポーネントのソースコードの詳細な分析

Element UIテーブルコンポーネントのソースコードの詳細な分析

不言
不言オリジナル
2018-07-25 10:23:393908ブラウズ

この記事では、以下の図に示すような最も基本的なテーブルから始めて、テーブル コンポーネントのソース コードを分析します。テーブルコンポーネントの元のソースコードを削除しました。この記事では、重要なコード スニペットのみを説明します。プロジェクトを実行するコードをダウンロードして、記事と合わせて読むことをお勧めします。

Idea

<template>
  <p>
    <!-- 隐藏列: slot里容纳table-column -->
    </p>
<p>
      <slot></slot>
    </p>

    <p>
      <table-header>
      </table-header>
    </p>

    <p>
      <table-body>                  
      </table-body>
    </p>
  
</template>

Table、table-header、table-body、table-column は、table-store を通じて管理されます。 table-header と table-body はテーブル ストア データを監視し、テーブルがテーブル ストア データを変更するたびに table-header と table-body をトリガーして再レンダリングします。

table-column は、テーブル本体をレンダリングするときに使用するために、対応する renderCell 関数を列データ列にバインドします。テーブル列コンポーネント自体はレンダリングを行いません。したがって、テンプレートがそれを隠していることがわかります。 render 関数を通じてレンダリングされる table-header と table-body もあります。

初期化シーケンス

Element UIテーブルコンポーネントのソースコードの詳細な分析

table

  1. ストアを初期化

    data() {
      const store = new TableStore(this);
      return {
        store,
      };
    }
  2. table-header、table-bodyにストアを共有

        <p>
          <table-header></table-header>
        </p>
    
        <p>
          <table-body></table-body>
        </p>
  3. テーブルに保存するストレージデータ- body はデータを取得してレンダリングします

    watch: {
        data: {
          immediate: true,
          handler(value) {
            // 供 table-body computed.data 使用 
            this.store.commit('setData', value);
            // ......
          }
        },
    },
  4. tableId を設定します

    created() {
          //.....
          this.tableId = `el-table_${tableIdSeed}`;
          //.....
      }
  5. updateColumns を呼び出してテーブルヘッダーとテーブル本体の二次レンダリング更新をトリガーし、マウントされた完了をマークします

    mounted() {
        // .....
        this.store.updateColumns();
        // .....
        this.$ready = true;
    }

table-column

  1. テーブル本体で使用するために列を生成し、列をバインドします

    created(){
          // .........
          let column = getDefaultColumn(type, {
              id: this.columnId,
              columnKey: this.columnKey,
              label: this.label,
              property: this.prop || this.property,// 旧版element ui为property,现在的版本是prop
              type, // selection、index、expand
              renderCell: null,
              renderHeader: this.renderHeader, // 提供给table-column, table-column.js line 112
              width,
              formatter: this.formatter,
              context: this.context,
              index: this.index,
            });
          // .........
          
          // 提table-body使用, table-body.js line 69
          column.renderCell = function (createElement, data) {
            if (_self.$scopedSlots.default) {
              renderCell = () => _self.$scopedSlots.default(data);
              //<template>
              //<span>{{row.frequentlyUsed | formatBoolean}}</span>
              //</template>
            }
      
            if (!renderCell) {// table-header不渲染index列的走这里,
              /*<p>王小虎</p>*/
              renderCell = DEFAULT_RENDER_CELL;
            }
      
            //  <eltablecolumn></eltablecolumn>
            return <p>{renderCell(createElement, data)}</p>;
          };
      
    }
    renderCell函数
  2. store.state._columns 配列にデータを入力します
  3. mounted() {
        // ...... 
        owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null);
    }

table-store

table-store には 2 つの非常に重要な要素があります属性 _columns、data、_columns は列関連の情報を保存し、data は開発者によって渡されたテーブル データを保存します。また、insertColumn と updateColumns という 2 つの重要な関数もあります。

    insertColumn は _columns のデータを入力します
  1. TableStore.prototype.mutations = {
      insertColumn(states, column, index, parent) {
        let array = states._columns;
        // ......
    
        if (typeof index !== 'undefined') {
          // 在index的位置插入column
          array.splice(index, 0, column);
        } else {
          array.push(column);
        }
    
        // .....
      },
    }

  2. updateColumns _columns をフィルターして列を取得します
  3. TableStore.prototype.updateColumns = function() {
      const states = this.states;
      const _columns = states._columns || [];
      
      const notFixedColumns = _columns.filter(column => !column.fixed);
      // .....
      const leafColumns = doFlattenColumns(notFixedColumns);
      // .....
      
      states.columns = [].concat(leafColumns);
      // ....
    }

table-header、table-body

table-header、table-body はすべて次の属性を持ちます

りー

これら 2 つのコンポーネントの動作原理は、列データの変更を監視してレンダリングをトリガーすることです。テーブル コンポーネントのマウント段階では、updateColumns が呼び出されて列が更新され、それによって table-header と table-body の再レンダリングがトリガーされます。

さらに、table-body はデータの変更を監視し、レンダリングをトリガーします。たとえば、コンポーネントがロードされると、リクエストが送信され、リクエストの応答にデータが割り当てられ、テーブル本体が再レンダリングされます。

props: {
    store: {
      required: true
    },
}

computed: {
    columns() {
      return this.store.states.columns;
    },
},

render(){
    // 渲染columns的数据
}

関連する推奨事項:

React コンポーネントでこれをバインドする理由の分析

Vue ソース コードのバッチ非同期更新と nextTick 原則の分析

以上がElement UIテーブルコンポーネントのソースコードの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。