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要素】画像の埋め込み方法

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

ブログ    

推薦する

ホームページのデザインはウェブデザイナーのレベルを最もよく反映する

私がこれまで携わってきた多くのプロジェクトでは、基本的に避けられない悪循環がありました。それは、ホー...

ウェブサイトのデザイン体験のための7つの異なるカラースキーム

ウェブサイト構築におけるカラーマッチングは非常に特殊であり、ウェブサイトのテーマ、感情、雰囲気などの...

2つのボールが交差する粘着効果を実現するCSSサンプルコード

これは純粋に CSS のみを使用して作成されたエフェクトです。簡単に言うと、このエフェクトは画像処理...

Linuxがすべてのコマンドをサポートしていない問題の解決策

Linux がすべてのコマンドをサポートしていない場合はどうすればいいですか?すべてのLinuxコマ...

MySQL ストアド プロシージャで case ステートメントを使用する詳細な例

この記事では、例を使用して、MySQL ストアド プロシージャでの case ステートメントの使用方...

MySQL データベース アーキテクチャの詳細

目次1. MySQL アーキテクチャ2. ネットワーク接続層3. データベースサービス層4. 接続プ...

HTML でテキストの折り返しを実装する例 (HTML でテキストと画像が混在)

1. 画像の周りのテキスト通常のものを使用する場合、たとえば次のようになります。コードをコピーコー...

nginx での listen ディレクティブの例の分析

プロットレビュー前回の記事では、ロケーション命令の解析プロセスを分析しました。この内容を簡単に確認し...

JavaScript の基礎: エラーキャプチャメカニズム

目次序文エラーオブジェクト投げる試して…捕まえて…最後に最終ルールトライ/キャッチパフォーマンスウィ...

Mysql関数呼び出しの最適化の詳細な説明

目次関数呼び出しの最適化関数呼び出しの最適化MySQL 関数は、内部的に決定論的または非決定論的とし...

JSは検証コードのランダム生成を実装します

この記事の例では、検証コードのランダム生成を実現するためのJSの具体的なコードを参考までに共有してい...

リアクトルーティングガード(ルーティングインターセプション)の実装

React は Vue とは異なります。ルートにメタ文字を設定することでルートインターセプションを実...

よく知られているブラウザのDOCTYPEモード選択メカニズム

ドキュメントの範囲この記事では、Firefox やその他の Gecko ベースのブラウザ、Safar...

CocosCreator 入門チュートリアル: TS で初めてのゲームを作る

目次前提TypeScript と JavaScriptコードエディタの選択TypeScriptを学ぶ...

HTML テーブルのオーバーフローの解決方法

テーブルが広い場合は、あふれてしまう可能性があります。たとえば、左と右の 2 つの div がありま...