您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery | 小程序 |

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

51自学网 2022-02-21 13:35:23
  javascript

效果

需要环境

vue
elementUI
拖拽插件Sortable.js

需配置属性

示例

<HTable  :columns="columns"  :data="list"  :setColumn="true"  tableKey="CategoriesList"  style="width: 100%"  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"            style="display:block;line-height:2;margin-right:0;"            >{{ 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封装的可拖拽行列、选择列组件的实现的文章就介绍到这了,更多相关el-table 可拖拽行列内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net!
下载地址:
Vue2&nbsp;cube-ui时间选择器详解
uniapp调用百度语音实现录音转文字功能

万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。