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

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

推薦する

HTMLを教える記事

アーティストになるつもりがない場合は、開発者として HTML を読んで、必要に応じて簡単な変更を加え...

::before/:before と ::after/:after の使用に関する深い理解

パート1: 基礎1. :active や :hover などの疑似クラスとは異なり、これらはすべて疑...

MySQLデータベースのスケジュールバックアップを実装する方法

1. シェルスクリプトを作成する vim バックアップdb.sh 次のようにスクリプトを作成します。...

Nginxはhttpとhttpsの両方のアクセスをサポートするために同じドメイン名を設定します

Nginx は同じドメイン名で構成されており、http と https の両方でアクセスできます。証...

CSSアニメーション効果アニメーションの一般的なスタイル

アニメーションアニメーションを定義します。 /*アニメーションの各ステップで実行されるアクションを定...

CSSでスペースを処理する方法

1. 宇宙のルールHTML コード内の空白は通常、ブラウザによって無視されます。 <p>...

Vue カプセル化コンポーネント アップロード画像コンポーネント

この記事の例では、参考のためにvueアップロード画像コンポーネントの具体的なコードを共有しています。...

MySQLとElasticsearch間のデータ非対称性問題の解決策

MySQLとElasticsearch間のデータ非対称性問題の解決策jdbc-input-plugi...

HTMLフォーム属性のreadonlyとdisabledの使い方

1. readonly 読み取り専用属性なので、値を取得できます2. 無効: 無効な属性、値を取得で...

MySQLのネクストキーロックのロック範囲についての簡単な説明

序文ある日、突然 MySQL の次のキー ロックについて尋ねられ、私の即座の反応は次のようなものでし...

Linux システムを起動時に自動的にスクリプトを実行するように設定する方法の例

序文みなさんこんにちは。私は梁旭です。職場では、システムの起動後にスクリプトやサービスを自動的に開始...

ウェブサイトをより高く、よりデザイン的に見せる方法

「ウェブサイトを高級感のあるものにするにはどうすればいいでしょうか? それともデザイン重視にすればい...

CSS における z-index: 0 と z-index: auto の違い

最近、スタック コンテキストについて学習しています。学習の過程で、z-index が 0 の場合と ...

Vueは物流タイムライン効果を実現します

この記事では、物流タイムライン効果を実現するためのVueの具体的なコードを例として紹介します。具体的...

Tomcat Nativeを使用してTomcat IO効率を向上させる方法の詳細な説明

目次導入Tomcatへの接続方法APR と Tomcat ネイティブtomcat で APR を使用...