文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何进行基于el-table封装的可拖拽行列、选择列组件的实现

2023-06-22 04:24

关注

本篇文章为大家展示了如何进行基于el-table封装的可拖拽行列、选择列组件的实现,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

效果

如何进行基于el-table封装的可拖拽行列、选择列组件的实现

需要环境

vue
elementUI
拖拽插件Sortable.js

需配置属性

如何进行基于el-table封装的可拖拽行列、选择列组件的实现

示例

<HTable  :columns="columns"  :data="list"  :setColumn="true"  tableKey="CategoriesList"    border>  // 这里可以放插槽  <template slot="create_time" slot-scope="scope">    {{ scope.column.label + scope.item.prop }}  </template>  <template slot="action" 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>  </template></HTable>import HTable from "@/components/HTable";export default {  components: { HTable },  data() {    return {      list: [],      columns: [        {          label: "ID", // 描述          prop: "_id", // 列的唯一值。 必须要有          checked: true // 是否展示该列          ... // 一些el-table-column的属性都可以写在这里        },        {          label: "分类名称",          prop: "name",          checked: true        },        {          label: "上级分类",          prop: "parent.name",          checked: true        },        {          label: "状态",          prop: "status",          width: "100",          checked: true        },        {          label: "创建时间",          prop: "create_time",          slotHeaderName: "create_time", // 自定义表头          checked: true        },        {          label: "操作",          prop: "action",          fixed: "right",          "min-width": "100",          slotName: "action", // 自定义单元格插槽          checked: true,          disabled: true        }      ]    };  }};

有用到的话给我点个赞!附组件代码

<template>  <div class="HTable">    <div class="settingBox" v-if="setColumn">      <el-popover        placement="bottom-end"        trigger="click"        popper-class="settingPopper"      >        <el-checkbox-group          v-model="selectCol"          @change="handleChangeSelectColumn"        >          <el-checkbox            v-for="item in col"            :key="item.prop"            :label="item.prop"            :disabled="item.disabled"                        >{{ item.label }}</el-checkbox          >        </el-checkbox-group>        <i class="icon el-icon-setting" slot="reference"></i>      </el-popover>    </div>    <el-table      v-bind="$attrs"      :data="tableData"      v-on="$listeners"      :key="JSON.stringify(checkedCol)"    >      <el-table-column        v-for="(item, index) in checkedCol"        :key="item.prop"        v-bind="item"        :index="index"        :column-key="item.prop"      >        <template v-if="item.slotHeaderName" v-slot:header="scope">          <slot :name="item.slotHeaderName" v-bind="scope" :item="item"></slot>        </template>        <template v-if="item.slotName" v-slot:default="scope">          <slot :name="item.slotName" v-bind="scope"></slot>        </template>      </el-table-column>    </el-table>  </div></template><script>import Sortable from "sortablejs";export default {  name: "HTable",  props: {    tableKey: String,    columns: {      type: Array,      default() {        return [];      }    },    data: {      type: Array,      default() {        return [];      }    },    setColumn: {      type: Boolean,      default: false    }  },  watch: {    columns: {      handler(newVal) {        let localVal = this.getStorageCol();        let hotVal = [];        if (localVal) {          hotVal = this.dataDiff(newVal, localVal);        } else {          hotVal = [...newVal];        }        this.col = hotVal.map(          (item, index) =>            (item = { ...item, index, checked: item.checked || false })        );        this.checkedCol = this.checkedColFun(this.col);        this.selectCol = this.checkedCol.map(item => (item = item.prop));      },      immediate: true    },    data: {      handler(newVal) {        this.tableData = [...newVal];      },      immediate: true    },    col: {      handler(newVal) {        this.setStorageCol(newVal);      },      deep: true,      immediate: true    }  },  data() {    return {      tableData: [],      col: [],      checkedCol: [],      selectCol: []    };  },  mounted() {    document.body.ondrop = function(event) {      event.preventDefault();      event.stopPropagation();    };    this.$nextTick(() => {      this.rowDrop();      this.columnDrop();    });  },  methods: {    drap() {      this.$nextTick(() => {        this.rowDrop();        this.columnDrop();      });    },    handleChangeSelectColumn() {      this.col.forEach(item => {        if (this.selectCol.includes(item.prop)) {          item.checked = true;        } else {          item.checked = false;        }      });      this.checkedCol = this.checkedColFun(this.col);      this.drap();    },    rowDrop() {      const tbody = document.querySelector(".el-table__body-wrapper tbody");      Sortable.create(tbody, {        onEnd: ({ newIndex, oldIndex }) => {          [this.tableData[newIndex], this.tableData[oldIndex]] = [            this.tableData[oldIndex],            this.tableData[newIndex]          ];          this.drap();          this.$emit("dropRow", {            drapRow: this.tableData[oldIndex],            targetRow: this.tableData[newIndex],            drapRowIndex: oldIndex,            targetRowIndex: newIndex,            data: this.tableData          });        }      });    },    columnDrop() {      const wrapperTr = document.querySelector(".el-table__header-wrapper tr");      Sortable.create(wrapperTr, {        animation: 180,        delay: 0,        onEnd: ({ newIndex, oldIndex }) => {          const oldItem = this.checkedCol[oldIndex];          const newItem = this.checkedCol[newIndex];          [this.col[newItem.index].index, this.col[oldItem.index].index] = [            oldItem.index,            newItem.index          ];          this.col.sort((a, b) => {            return a.index - b.index;          });          this.checkedCol = this.checkedColFun(this.col);          this.tableData = this.tableData.slice(0, this.tableData.length);          this.drap();          this.$emit("dropCol", {            colItem: oldItem,            newIndex: newIndex,            oldIndex: oldIndex,            column: this.checkedCol          });        }      });    },    checkedColFun(arr) {      return arr.filter(item => item.checked);    },    setStorageCol(data) {      if (this.tableKey && data && data.length > 0) {        localStorage.setItem("HTable-" + this.tableKey, JSON.stringify(data));      }    },    getStorageCol() {      let datajson = localStorage.getItem("HTable-" + this.tableKey);      return datajson ? JSON.parse(datajson) : "";    },    dataDiff(newVal, localVal) {      let nl = newVal.length;      let ll = localVal.length;      if (nl != ll) {        return newVal;      } else {        let np = newVal.map(item => item.prop).sort();        let lp = localVal.map(item => item.prop).sort();        if (np.join() != lp.join()) {          return newVal;        } else {          let nnl = [];          for (let i = 0; i < localVal.length; i++) {            const item_l = localVal[i];            for (let j = 0; j < newVal.length; j++) {              const item_n = newVal[j];              if (item_l.prop === item_n.prop) {                nnl.push({                  ...item_n,                  index: item_l.index                });              }            }          }          return nnl;        }      }    }  }};</script><style lang="less" scoped>.HTable {  position: relative;  .settingBox {    width: 36px;    height: 36px;    border-radius: 2px;    border: 1px solid #ebeef5;    border-bottom: 0;    margin-left: auto;    position: relative;    .icon {      position: absolute;      top: 0;      left: 0;      z-index: 1;      width: 36px;      height: 36px;      text-align: center;      font-size: 20px;      line-height: 36px;      color: #909399;      cursor: pointer;    }  }}</style><style lang="less">.settingPopper {  min-width: 100px !important;}</style>

上述内容就是如何进行基于el-table封装的可拖拽行列、选择列组件的实现,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯