el-table カプセル化に基づくドラッグ可能な行と列、および選択列コンポーネントの実装

el-table カプセル化に基づくドラッグ可能な行と列、および選択列コンポーネントの実装

効果

環境が必要

ビュー
要素UI
ドラッグアンドドロッププラグインSortable.js

必要な構成プロパティ


<Hテーブル
  :columns="列"
  :data="リスト"
  :setColumn="true"
  tableKey="カテゴリリスト"
  スタイル="幅: 100%"
  国境
>
  // ここにスロットを置くことができます <template slot="create_time" slot-scope="scope">
    {{ スコープ.列.ラベル + スコープ.アイテム.プロパティ }}
  </テンプレート>
  <テンプレート スロット="アクション" スロット スコープ="スコープ">
    <el-button type="primary" @click="handleEdit(scope.row)" size="small">
      編集</el-button>
    <el-button @click="handleDelete(scope.row)" type="danger" size="small">
      削除</el-button>
  </テンプレート>
</HTable>
"@/components/HTable" から HTable をインポートします。

エクスポートデフォルト{
  コンポーネント: { HTable },
  データ() {
    戻る {
      リスト: [],
      列: [
        {
          label: "ID", // 説明 prop: "_id", // 列の一意の値。 チェックされている必要があります: true // この列を表示するかどうか... // ここでいくつかの el-table-column 属性を記述できます},
        {
          ラベル: "カテゴリ名",
          プロパティ: "名前",
          チェック済み: true
        },
        {
          ラベル: 「優秀カテゴリー」、
          プロパティ: "親.名前",
          チェック済み: true
        },
        {
          ラベル: "ステータス",
          プロパティ: "ステータス",
          幅: "100",
          チェック済み: true
        },
        {
          ラベル: 「作成時間」、
          プロパティ: "create_time",
          slotHeaderName: "create_time", // カスタム ヘッダーがチェックされています: true
        },
        {
          ラベル: "操作",
          プロップ: "アクション",
          修正: 「正しい」、
          "最小幅": "100",
          slotName: "action", // カスタムセルスロットがチェックされています: true,
          無効: true
        }
      ]
    };
  }
};

役に立った場合は高評価をお願いします!添付コンポーネントコード

<テンプレート>
  <div class="HTable">
    <div class="settingBox" v-if="setColumn">
      <el-popover
        配置="下端"
        トリガー="クリック"
        ポッパークラス="settingPopper"
      >
        <el-チェックボックスグループ
          v-model="selectCol"
          @change="handleChangeSelectColumn"
        >
          <el-チェックボックス
            v-for="col 内の項目"
            :key="アイテム.prop"
            :label="アイテム.prop"
            :disabled="アイテムが無効"
            スタイル="display:block;line-height:2;margin-right:0;"
            >{{ item.label }}</el-checkbox
          >
        </el-チェックボックスグループ>
        <i class="icon el-icon-setting" slot="reference"></i>
      </el-popover>
    </div>
    <el-テーブル
      v-bind="$attrs"
      :data="テーブルデータ"
      v-on="$リスナー"
      :key="JSON.stringify(チェックされた列)"
    >
      <el-テーブル列
        v-for="(item, index) in selectedCol"
        :key="アイテム.prop"
        v-bind="アイテム"
        :index="インデックス"
        :column-key="item.prop"
      >
        <テンプレート v-if="item.slotHeaderName" v-slot:header="scope">
          <スロット:name="item.slotHeaderName" v-bind="scope" :item="item"></スロット>
        </テンプレート>
        <テンプレート v-if="item.slotName" v-slot:default="スコープ">
          <スロット:name="item.slotName" v-bind="scope"></スロット>
        </テンプレート>
      </el-table-column>
    </el-table>
  </div>
</テンプレート>

<スクリプト>
「sortablejs」からSortableをインポートします。
エクスポートデフォルト{
  名前: "HTable",
  小道具: {
    テーブルキー: 文字列、
    列: {
      タイプ: 配列、
      デフォルト() {
        戻る [];
      }
    },
    データ: {
      タイプ: 配列、
      デフォルト() {
        戻る [];
      }
    },
    列の設定: {
      タイプ: ブール値、
      デフォルト: false
    }
  },
  時計:
    列: {
      ハンドラ(newVal) {
        localVal を this.getStorageCol() とします。
        hotVal = [] とします。
        if (localVal) {
          hotVal = this.dataDiff(newVal, localVal);
        } それ以外 {
          hotVal = [...newVal];
        }
        this.col = hotVal.map(
          (項目、インデックス) =>
            (item = { ...item, index, チェック済み: item.checked || false })
        );
        this.checkedCol = this.checkedColFun(this.col);
        this.selectCol = this.checkedCol.map(item => (item = item.prop));
      },
      即時: 真
    },
    データ: {
      ハンドラ(newVal) {
        this.tableData = [...newVal];
      },
      即時: 真
    },
    列: {
      ハンドラ(newVal) {
        this.setStorageCol(新しい値);
      },
      深い:本当、
      即時: 真
    }
  },
  データ() {
    戻る {
      テーブルデータ: [],
      列: [],
      チェックされた列: [],
      選択列: []
    };
  },

  マウント() {
    document.body.ondrop = 関数(イベント) {
      イベントをデフォルトにしない();
      イベントの伝播を停止します。
    };
    this.$nextTick(() => {
      この行をドロップします。
      this.columnDrop();
    });
  },
  メソッド: {
    ドラップ(){
      this.$nextTick(() => {
        この行をドロップします。
        this.columnDrop();
      });
    },

    ハンドル変更選択列() {
      this.col.forEach(item => {
        if (this.selectCol.includes(item.prop)) {
          項目がチェックされている = true;
        } それ以外 {
          項目がチェックされている = false;
        }
      });
      this.checkedCol = this.checkedColFun(this.col);
      これをdrap()します。
    },

    行ドロップ() {
      const tbody = document.querySelector(".el-table__body-wrapper tbody");
      ソート可能.create(tbody, {
        onEnd: ({ 新しいインデックス、 古いインデックス }) => {
          [this.tableData[新しいインデックス], this.tableData[古いインデックス]] = [
            this.tableData[古いインデックス]、
            this.tableData[新しいインデックス]
          ];
          これをdrap()します。
          this.$emit("dropRow", {
            drapRow: this.tableData[oldIndex],
            ターゲット行: this.tableData[newIndex],
            drapRowIndex: 古いインデックス、
            ターゲット行インデックス: 新しいインデックス、
            データ: this.tableData
          });
        }
      });
    },
    列ドロップ() {
      const wrapperTr = document.querySelector(".el-table__header-wrapper tr");
      ソート可能.create(ラッパーTr, {
        アニメーション: 180,
        遅延: 0,
        onEnd: ({ 新しいインデックス、 古いインデックス }) => {
          const oldItem = this.checkedCol[oldIndex];
          const newItem = this.checkedCol[newIndex];
          [this.col[newItem.index].index, this.col[oldItem.index].index] = [
            古いアイテムのインデックス、
            新しいアイテムインデックス
          ];
          this.col.sort((a, b) => {
            a.index - b.index を返します。
          });
          this.checkedCol = this.checkedColFun(this.col);
          this.tableData = this.tableData.slice(0, this.tableData.length);
          これをdrap()します。
          this.$emit("dropCol", {
            colItem: 古いアイテム、
            新しいインデックス: 新しいインデックス、
            古いインデックス: 古いインデックス、
            列: this.checkedCol
          });
        }
      });
    },
    チェックされたColFun(arr) {
      arr.filter(item => item.checked); を返します。
    },
    setStorageCol(データ) {
      if (this.tableKey && data && data.length > 0) {
        localStorage.setItem("HTable-" + this.tableKey, JSON.stringify(data));
      }
    },
    ストレージ列を取得する() {
      datajson = localStorage.getItem("HTable-" + this.tableKey);
      datajson を返します? JSON.parse(datajson): "";
    },
    dataDiff(新しい値、ローカル値) {
      nl = newVal.length;とします。
      ll = localVal.lengthとします。
      もし (nl != ll) {
        newVal を返します。
      } それ以外 {
        np = newVal.map(item => item.prop).sort() とします。
        lp = localVal.map(item => item.prop).sort() とします。
        np.join() != lp.join() の場合 {
          newVal を返します。
        } それ以外 {
          nnl = [] とします。
          (i = 0 とします; i < localVal.length; i++) {
            定数item_l = localVal[i];
            (j = 0; j < newVal.length; j++) の場合 {
              定数item_n = newVal[j];
              (item_l.prop === item_n.prop)の場合{
                nnl.push({
                  ...アイテムn、
                  インデックス: item_l.index
                });
              }
            }
          }
          nnl を返します。
        }
      }
    }
  }
};
</スクリプト>

<style lang="less" スコープ>
.HTable {
  位置: 相対的;
  .settingBox{
    幅: 36ピクセル;
    高さ: 36px;
    境界線の半径: 2px;
    境界線: 1px 実線 #ebeef5;
    下境界線: 0;
    左マージン: 自動;
    位置: 相対的;
    .アイコン {
      位置: 絶対;
      上: 0;
      左: 0;
      zインデックス: 1;
      幅: 36ピクセル;
      高さ: 36px;
      テキスト配置: 中央;
      フォントサイズ: 20px;
      行の高さ: 36px;
      色: #909399;
      カーソル: ポインタ;
    }
  }
}
</スタイル>
<スタイル lang="less">
.settingPopper{
  最小幅: 100px !重要;
}
</スタイル>

el-table カプセル化に基づくドラッグ可能な行と列、および選択列コンポーネントの実装に関するこの記事はこれで終わりです。el-table のドラッグ可能な行と列に関するより関連性の高い記事については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • el-table ヘッダーでテキストを折り返す 3 つの方法の詳細な説明
  • Vue の el-table は自動天井効果を実現します (固定をサポート)
  • Vue+el-tableはセルの結合を実現します
  • vueはel-tableの列幅の適応を完璧に実現します
  • 要素 el-table テーブルの二次カプセル化 (テーブルの高さの調整付き)
  • vue は sortable を使用して el-table のドラッグ アンド ドロップによるソート機能を実装します。
  • Vue で要素の el-table スタイルを変更する 4 つの方法
  • vue+elementはel-tableの行の添え字を取得し、添え字に従って配列オブジェクトを操作します。
  • vue el-table はカスタム テーブル ヘッダーを実装します
  • Vue el-table はインライン編集機能を実現します

<<:  【HTML要素】画像の埋め込み方法

>>:  ページ要素の絶対位置と相対位置に関するある程度の理解

推薦する

Linux で FTP イメージ サーバーをインストールして展開する方法

Linux で FTP サーバーを設定するためのチュートリアルを参照してください https://w...

js オプション連鎖演算子の使用

序文オプションの連鎖演算子 (?.) を使用すると、チェーン内の各参照が有効であることを明示的に検証...

JSでHTML本文のスタイルを変更する

目次1. 本来の定義2. JS操作、幅の変更を例に3. 効果: 幅が変更されました 1. 本来の定義...

MySQLのサブクエリユニオンの効率性についての簡単な説明と

最近の製品テストでは、同時呼び出し数が 10 未満の場合に応答時間が 100 ミリ秒以内に維持できな...

Vue3 でサードパーティのコンポーネントライブラリをオンデマンドでロードする方法

序文Element Plus を例に、コンポーネントとスタイルのオンデマンド読み込みを構成します。環...

知っておくべき 25 の Vue のヒント

目次1. プロパティを型リストに制限する2. デフォルトのコンテンツと拡張ポイント3. ネストされた...

docker を使用して influxdb と mongo をデプロイするための一般的なコマンド

Docker ベースのデータベースをデプロイするsudo docker pull influxdb ...

モバイルデバイス上のぼやけた小さなアイコンの問題を解決する方法

序文以前、画像とテキストの垂直方向のずれの問題について説明しました。ここで示した小さな例では、小さな...

Docker の MySQL コンテナのタイムゾーン問題の修正

序文Ahhang が Springboot プロジェクトを開発していたとき、フロントエンドから検証コ...

JavaScript es6 の新しい配列メソッドの詳細な説明

目次1. 各() 2. arr.filter() 3. arr.every() 4. arr.map...

フォームタグの Enctype 属性とその応用例の紹介

Enctype : ブラウザがデータをサーバーに送り返すときに使用するエンコーディングのタイプを指定...

Mac VMware Fusion CentOS7 静的 IP 構成チュートリアル図

目次CentOS7をインストールする静的IPの設定viを使用してファイルを編集するCentOS7をイ...

MySQL マルチテーブル結合クエリ例の説明

実際のプロジェクトでは、複数のテーブル間に関係が存在します。 1 つのテーブル内のすべてのデータを取...

mysql エラー 1045 (28000) - ユーザーへのアクセスが拒否される問題を解決する方法

問題の説明 (以下の説明は Windows 環境に限定されます): D:\develop\ide\m...

MySQL 8.0 バージョンで getTables がすべてのデータベース テーブルを返す問題の簡単な分析

序文この記事では、主にライブラリ内のすべてのテーブルを返すMysql8.0ドライバgetTables...