Vue+Element Ui实现el-table自定义表头下拉选择表头筛选

这篇具有很好参考价值的文章主要介绍了Vue+Element Ui实现el-table自定义表头下拉选择表头筛选。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

用vue+element ui开发管理系统时,使用el-table做表格,当表格列过多的时候,想要做成可选表头的,实现表格列的筛选显示,效果如下:

Vue+Element Ui实现el-table自定义表头下拉选择表头筛选,vue.js,javascript,前端,elementui,vue

代码文件结构:

Vue+Element Ui实现el-table自定义表头下拉选择表头筛选,vue.js,javascript,前端,elementui,vue

废话不多说,直接上代码:

第一步:新建名为 TableHeaderRender.vue 的文件

<template>

  <el-popover

    placement="bottom"

    width="200"

    trigger="manual"

    v-model="visible"

    @show="showPopover"

    popper-class="table-header-popover"

  >

    <div class="table-header-popover-template">

      <el-input

        placeholder="请输入内容"

        v-model="value"

        size="small"

        clearable

        @keyup.enter.native="confirm"

        ref="sInput"

      >

        <!-- <el-button slot="append" icon="el-icon-search" @click="confirm"> -->

        <!-- </el-button> -->

      </el-input>

    </div>

    <div class="el-table-filter__bottom">

      <button @click="confirm">筛选</button>

      <button @click="resetData">重置</button>

    </div>

    <span

      slot="reference"

      style="margin-left: 5px"

      @click.stop="popClick"

      v-click-outside="closeOver"

    >

      <i

        class="filter-icon el-icon-search"

        :style="{ color: iconColor ? '#9a4b9b' : '#909399' }"

      ></i>

      <!-- <i class="el-icon-search" :style="{'color':iconColor}" ></i> -->

      <!-- <svg

        viewBox="64 64 896 896"

        data-icon="search"

        width="1em"

        height="1em"

        fill="currentColor"

        :style="{

          color: iconColor ? '#9A4B9B' : '',

          'margin-right': '2px',

          cursor: 'pointer',

        }"

      >

        <path

          d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"

        ></path>

      </svg> -->

    </span>

  </el-popover>

</template>

<script>

export default {

  name: "tableHeaderRender",

  data() {

    return {

      // input 绑定的值

      value: "",

      visible: false,

      iconColor: false,

    };

  },

  props: {

    tableColumn: {

      type: Object,

      default: () => {},

    },

    columnProp: {

      type: String,

      default: "",

    },

    defaultValue: {

      type: String,

      default: "",

    },

    inputFilteredMap: {

      type: Object,

      default: () => {},

    },

  },

  created() {

    this.value = this.defaultValue;

    this.iconColor = this.value.trim() ? true : false;

  },

  methods: {

    showPopover() {

      this.$nextTick(() => {

        this.$refs.sInput.focus();

      });

    },

    resetData() {

      console.log("reset");

      this.value = "";

      this.visible = false;

      this.iconColor = false;

      const self = this;

      if (this.inputFilteredMap[self.columnProp]) {

        delete this.inputFilteredMap[self.columnProp];

      }

      self.$emit("resetChangeMethod", this.tableColumn, self.columnProp);

    },

    closeOver() {

      this.visible = false;

    },

    popClick(e) {

      // e.stopPropagation()

      this.visible = !this.visible;

    },

    confirm() {

      this.visible = false;

      if (this.value.trim()) {

        this.iconColor = true;

        this.inputFilteredMap[this.columnProp] = this.value;

        this.$emit(

          "filterInputMethod",

          this.tableColumn,

          this.inputFilteredMap

        );

      } else {

        // 如果搜索input输入为空,等同重置

        this.resetData();

      }

    },

  },

  directives: {

    clickOutside: {

      bind(el, binding, vnode) {

        function clickHandler(e) {

          // 这里判断点击的元素是否是本身,是本身,则返回

          if (el.contains(e.target)) {

            return false;

          }

          // 判断指令中是否绑定了函数

          if (binding.expression) {

            // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法

            binding.value(e);

          }

        }

        // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听

        el.__vueClickOutside__ = clickHandler;

        document.addEventListener("click", clickHandler);

      },

      update() {},

      unbind(el, binding) {

        // 解除事件监听

        document.removeEventListener("click", el.__vueClickOutside__);

        delete el.__vueClickOutside__;

      },

    },

  },

};

</script>

<style>

.filter-icon {

  font-size: 14px;

  color: #909399;

  cursor: pointer;

  font-weight: 400;

}

.table-header-popover {

  padding: 0;

}

.table-header-popover .table-header-popover-template {

  margin: 10px;

}

</style>




 

第二步:新建名为 operateTable.vue 的文件

<template>

  <div class="operateTable">

    <el-dropdown

      size="small"

      trigger="click"

      v-if="options.columnsSelect || options.columnsTreeSelect"

      class="column-dropdown"

    >

      <el-button style="padding: 9px 10px!important" size="small">

        <i style="font-size: 12px" class="el-icon-menu"></i>

        <i class="el-icon-arrow-down el-icon--right"></i>

      </el-button>

      <el-dropdown-menu slot="dropdown">

        <div style="margin:10px;" class="caoz_ft_warp" v-if="isInit||isSave">

          <el-button

            v-if="isInit"

            size="small"

            type="primary" 

            plain

            style="width:70px;"

            @click="initColumns(true)"

          >初始化</el-button>

          <el-button

            v-if="isSave"

            size="small"

            type="primary" 

            plain

            style="width:70px;"

            @click="$emit('saveSettingColumns',checkedList)"

           >保存</el-button>

        </div>

        <div style="margin:10px;" class="caoz_ft_warp">

          <el-input size="small" placeholder="请输入关键字" v-model="cloumnKeyword" clearable></el-input>

        </div>

        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" style="padding-left:10px;">Select All</el-checkbox>

        <el-checkbox-group

          v-if="!options.columnsTreeSelect"

          v-model="checkedList"

          style="max-height: 300px"

          @change="handleCheckedCitiesChange"

        >

          <div class="checkboxScorll">

            <template v-for="(option, index) in checkBoxOptions">

              <template v-if="cloumnKeyword && option.toLowerCase().indexOf(cloumnKeyword.toLowerCase())>-1">

                <el-checkbox

                  :key="index"

                  class="checkbox"

                  :label="option"

                ></el-checkbox>

              </template>

              <template v-else-if="!cloumnKeyword">

                <el-checkbox

                  :key="index"

                  class="checkbox"

                  :label="option"

                ></el-checkbox>

              </template>

              <template v-else></template>

            </template>

          </div>

        </el-checkbox-group>

        <div v-else class="checkboxTree">

          <el-tree

            ref="tree"

            :check-on-click-node="true"

            :data="treeColumn"

            show-checkbox

            node-key="label"

            :default-expanded-keys="defaultExpanded"

            :default-checked-keys="defaultChecked"

            :props="{

              children: 'children',

              label: 'label',

            }"

            @check="checkChange"

            style="max-height: 300px; overflow-y: auto"

          >

          </el-tree>

        </div>

      </el-dropdown-menu>

    </el-dropdown>

    <el-table

      id="iTable"

      ref="operateTable"

      border

      :data="dataSource"

      :stripe="options.stripe"

      :highlight-current-row="options.highlightCurrentRow"

      :max-height="options.maxHeight"

      :size="options.size"

      :fit="options.fit"

      :show-header="options.showHeader"

      :empty-text="options.emptyText"

      :default-sort="options.defaultSort"

      :row-key="getRowKeys"

      :default-expand-all="options.defaultExpandAll"

      :tree-props="options.treeProps"

      :lazy="options.lazy"

      :load="load"

      @cell-mouse-enter="cellMouseEnter"

      @cell-mouse-leave="cellMouseLeave"

      @cell-click="cellClick"

      @cell-dblclick="cellDblclick"

      @row-click="rowClick"

      @row-contextmenu="rowContextmenu"

      @row-dblclick="rowDblclick"

      @header-click="headerClick"

      @header-contextmenu="headerContextmenu"

      @sort-change="sortChange"

      @select="select"

      @select-all="selectAll"

      @selection-change="checkboxSelected"

      @filter-change="filterChange"

    >

      <slot name="expandRow"></slot>

      <!-- 复选框 -->

      <el-table-column

        :reserve-selection="options.reserveSelection"

        :key="0"

        type="selection"

        :selectable="selectable"

        width="40"

        align="left"

        v-if="options.showCheckBox"

        :resizable="false"

      >

      </el-table-column>

      <el-table-column

        ref="fixedColumn"

        label="操作"

        align="left"

        :width="operates.dropDown ? '50' : operates.width"

        :fixed="operates.fixed"

        :min-width="operates.minwidth"

        :resizable="operates.resizable"

        v-if="operates.list.length > 0"

      >

        <template slot-scope="scope">

          <!-- 操作列 不折叠 全为icon-->

          <div

            class="operate-group"

            v-if="!operates.dropDown && !operates.isText"

          >

            <template

              v-for="item in operates.list[0] instanceof Array

                ? operates.list[scope.$index]

                : operates.list"

            >

              <div class="item" v-if="item.show" :key="item.id">

                <el-switch

                  v-if="item.type === 'switch'"

                  v-model="scope.row[item.prop]"

                  active-color="#13ce66"

                  @change="item.method(scope.$index, scope.row)"

                ></el-switch>

                <el-tooltip

                  v-else-if="item.type === 'tooltipIcon'"

                  :enterable="false"

                  effect="light"

                  placement="bottom"

                >

                  <div slot="content">{{ item.tooltip }}</div>

                  <el-button 

                    type="primary" 

                    plain 

                    :icon="item.icon"

                    size="mini" 

                    :disabled="item.disabled"

                    @click="item.method(scope.$index, scope.row)"

                  ></el-button>

                </el-tooltip>

                <el-button 

                  v-else-if="item.type === 'icon'"

                  type="primary" 

                  plain 

                  :icon="item.icon"

                  size="mini" 

                  :disabled="item.disabled"

                  @click="item.method(scope.$index, scope.row)"

                ></el-button>

              </div>

            </template>

          </div>

          <!-- 操作列 不折叠 全为文字-->

          <div

            class="operate-group"

            v-if="!operates.dropDown && operates.isText"

          >

            <template

              v-for="item in operates.list[0] instanceof Array

                ? operates.list[scope.$index]

                : operates.list"

            >

              <div class="item" v-if="item.show" :key="item.id">

                <el-button

                  size="small"

                  type="text"

                  :disabled="item.disabled"

                  @click.native.prevent="item.method(scope.$index, scope.row)"

                  >{{ item.label }}</el-button

                >

              </div>

            </template>

          </div>

          <!-- 操作列 折叠下拉-->

          <div class="operate-group" v-else-if="operates.dropDown">

            <el-dropdown

              @command="handleCommand"

              trigger="hover"

              placement="bottom-start"

            >

              <span class="el-dropdown-link">

                <i class="el-icon-s-unfold" style="font-size: 16px;"></i>

              </span>

              <!-- 根据operates.list 来渲染操作列下拉的内容 -->

              <el-dropdown-menu slot="dropdown">

                <el-dropdown-item

                  v-for="(item, index) in operates.list[0] instanceof Array

                    ? operates.list[scope.$index]

                    : operates.list"

                  :disabled="item.disabled"

                  :key="index"

                  :command="composeValue(item, scope.row, scope.$index)"

                  >{{ item.label }}</el-dropdown-item

                >

              </el-dropdown-menu>

            </el-dropdown>

          </div>

        </template>

      </el-table-column>

      <!--region 数据列-->

      <template v-for="column in columns">

        <!-- :filter-method="column.filters ? column.filterMethod : undefined" -->

        <!-- v-if="

            options.columnsSelect || options.columnsTreeSelect

              ? checkedList.includes(column.label)

              : true

          " -->

        <el-table-column

          v-if="

            options.columnsSelect || options.columnsTreeSelect

              ? checkedList.includes(column.label)

              : true

          "

          :prop="column.prop"

          :key="column.label"

          :label="column.label"

          align="left"

          :width="column.width"

          :min-width="column.minwidth"

          :resizable="column.resizable"

          :sortable="column.sortable"

          :filters="column.filters"

          :filter-method="column.filters ? column.filterMethod : undefined"

          :filtered-value="column.filteredValue"

          :fixed="column.fixed"

          :column-key="column.prop"

        >

          <template slot="header" slot-scope="scope"

            >{{ column.label }}

            <TableHeaderRender

              v-if="column.filterInput"

              :columnProp="column.prop"

              :tableColumn="scope.column"

              :defaultValue="column.defaultValue"

              :inputFilteredMap="inputFilteredMap"

              @filterInputMethod="filterInputMethod"

              @resetChangeMethod="resetChangeMethod"

            ></TableHeaderRender>

          </template>

          <!-- :filtered-value="column.filteredValue" -->

          <template slot-scope="scope">

            <!-- 如果传进来的column没有render函数执行以下代码 -->

            <template v-if="!column.render">

              <!-- 如果传进来的column没有render函数但有formatter函数执行以下代码 -->

              <template v-if="column.formatter">

                <span v-html="column.formatter(scope.row, column)"></span>

              </template>

              <!-- 如果传进来的column既没有render函数也没有formatter函数执行以下代码 -->

              <template v-else>

                <span>{{ scope.row[column.prop] }}</span>

              </template>

            </template>

            <!-- 如果传进来的column有render函数执行以下代码 -->

            <template v-else>

              <expand-dom

                :column="column"

                :row="scope.row"

                :render="column.render"

                :index="scope.$index"

              ></expand-dom>

            </template>

          </template>

        </el-table-column>

      </template>

      <!--endregion-->

    </el-table>

  </div>

</template>

<script>

import TableHeaderRender from "./TableHeaderRender.vue";

export default {

  name: "OperateTable",

  props: {

    // 表格的数据源

    dataSource: {

      type: Array,

      default: () => [],

    },

    // 需要展示的列

    columns: {

      type: Array,

      default: () => [{}],

    },

    // table 表格的控制参数

    options: {

      type: Object,

      default: () => {

        return {

          stripe: true, // 是否为斑马纹 table

        };

      },

    },

    // 操作按钮组 === label: 文本,show:是否显示,icon:按钮图标,disabled:是否禁用,method:回调方法, 等等

    operates: {

      type: Object,

      default: () => {

        return {

          list: [],

        };

      },

    },

    defaultSelectedColumn: {

      type: Array,

      default: () => [],

    },

    defaultColumn: {

      type: Array,

      default: () => [],

    },

    totalColumn: {

      type: Array,

      default: () => [],

    },

    treeColumn: {

      type: Array,

      default: () => [],

    },

    defaultChecked: {

      type: Array,

      default: () => [],

    },

    defaultExpanded: {

      type: Array,

      default: () => [],

    },

    isInit: {

      type: Boolean,

      default: false

    },

    isSave: {

      type: Boolean,

      default: false

    }

  },

  components: {

    TableHeaderRender,

    expandDom: {

      functional: true,

      props: {

        row: Object,

        render: Function,

        index: Number,

        column: {

          type: Object,

          default: null,

        },

      },

      render: (h, ctx) => {

        const params = {

          row: ctx.props.row,

          index: ctx.props.index,

        };

        if (ctx.props.column) params.column = ctx.props.column;

        return ctx.props.render(h, params);

      },

    },

  },

  data() {

    return {

      cloumnKeyword:"",//字段关键字搜索

      isIndeterminate:true,//全选状态

      checkAll:false,//字段全选

      checkBoxOptions: [], // 全部表头

      checkedList: [], // 选中表头

      count: 0, // 用于判断表格是否刚渲染

      isCheckBoxSort: false, // 用于判断是否是由自定义数据列引发的排序

      // 以下是之前放于vuex中用于记录状态

      preCheckedList: [], // 前一次的checkbox

      // 排序的状态

      sort: {

        prop: "",

        order: "",

        label: "",

      },

      // 筛选的状态

      checkBoxFilteredMap: {},

      // input 所有的筛选

      inputFilteredMap: {},

      // columns label及prop对应的键值对

      columnsLabelMap: {}

    };

  },

  watch: {

    // 监听defaultColumn,若这个发生变化,代表传入的默认column变化,即数据表格发生了切换

    defaultColumn() {

      this.initColumns();

    },

    checkedList() {

      // if(this.checkedList.length>0){

      //   this.$emit("selectedColumn",this.checkedList);

      // }

      // 处理当点击checkbox显示的是排序列时,恢复排序列的显示

      let showLabelArray = this.checkboxShowLabel();

      console.log("showLabelArray", showLabelArray);

      // if (value.length !== 0) {

      //   value.map((item) => {

      //     this.handleStatusRevert(item);

      //   });

      this.columns.map((column, index) => {

        this.handleStatusRevert(column, index, showLabelArray);

      });

    },

  },

  created() {

    this.normalizeColumnsLabelMap();

  },

  mounted() {

    if (!this.options.columnsTreeSelect) {

      this.checkedList = this.$props.defaultColumn;

      this.checkBoxOptions = this.$props.totalColumn;

    } else {

      this.checkedList = this.$refs.tree

        .getCheckedNodes()

        .map((item) => item.label);

    }

    // 挂载时将defaultSort属性传给vuex

    this.handleDefaultSort();

  },

  // 动态切换表头的时候闪烁是因为表头重新计算高度导致的,以下方法解决此bug

  beforeUpdate() {

    this.$nextTick(() => {

      //在数据加载完,重新渲染表格

      this.$refs["operateTable"].doLayout();

    });

  },

  methods: {

    //全选字段

    handleCheckAllChange(val){

      this.checkedList = val ? this.checkBoxOptions : [];

      this.isIndeterminate = false;

    },

    //反选

    handleCheckedCitiesChange(value){

      let checkedCount = value.length;

      this.checkAll = checkedCount === this.checkBoxOptions.length;

      this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkBoxOptions.length;

    },

    //初始化字段

    initColumns(flag){

      if(flag){

        this.checkedList = this.$props.defaultSelectedColumn;

      }else{

        this.checkedList = this.$props.defaultColumn;

      }

      this.checkBoxOptions = this.$props.totalColumn;

    },

    // 处理判断checkbox 点击时,显示的是哪个字段名

    checkboxShowLabel() {

      // 判断显示的字段是哪个字段,如果是树形,可能有多个,故更改为数组接收

      let value = [];

      console.log("this.checkedList", this.checkedList);

      if (this.count === 0) {

        this.saveCheckedList(this.checkedList);

        // this.$componentsStore.commit("table/saveCheckedList", this.checkedList);

        this.count++;

      } else {

        if (this.checkedList.length > this.preCheckedList.length) {

          for (let index = 0; index < this.checkedList.length; index++) {

            if (!this.preCheckedList.includes(this.checkedList[index])) {

              value.push(this.checkedList[index]);

            }

            // if (this.checkedList[index] !== this.preCheckedList[index]) {

            //   value = this.checkedList[index];

            // }

          }

        }

        this.saveCheckedList(this.checkedList);

        // this.$componentsStore.commit("table/saveCheckedList", this.checkedList);

      }

      return value;

    },

    // 处理sort\filterd由隐藏变为显示状态的恢复

    handleStatusRevert(column, index, showLabelArray) {

      let compareLabel = column.label;

      if (showLabelArray.includes(compareLabel)) {

        // 如果是有checkbox 筛选的字段,恢复筛选

        let filteredValue =

          this.checkBoxFilteredMap[this.columnsLabelMap[compareLabel]];

        // 如果是有input 筛选的字段,恢复筛选

        let filteredInputValue =

          this.inputFilteredMap[this.columnsLabelMap[compareLabel]];

        this.columns[index].filteredValue = filteredValue;

        this.columns[index].defaultValue = filteredInputValue;

        this.$nextTick(() => {

          this.$refs.operateTable.store.states.columns.map((column) => {

            if (column.filteredValue && column.filteredValue.length) {

              this.$refs.operateTable.store.commit("filterChange", {

                column,

                values: column.filteredValue,

                silent: true,

              });

            }

          });

        });

      } else {

        this.columns[index].filteredValue = [];

        this.columns[index].defaultValue = "";

      }

      // 如果是有排序的字段,恢复排序

      if (showLabelArray.includes(this.sort.label)) {

        this.$nextTick(() => {

          //在数据加载完,重新渲染表格

          this.isCheckBoxSort = true;

          this.$refs.operateTable.sort(this.sort.prop, this.sort.order);

        });

      }

      /**

      // 如果是有checkbox 筛选的字段,恢复筛选

      let filteredValue = this.checkBoxFilteredMap[this.columnsLabelMap[value]];

      // 如果是有input 筛选的字段,恢复筛选

      let filteredInputValue = this.inputFilteredMap[

        this.columnsLabelMap[value]

      ];

      for (let i = 0; i < this.columns.length; i++) {

        if (this.columns[i].label === value) {

          this.columns[i].filteredValue = filteredValue;

          this.columns[i].defaultValue = filteredInputValue;

          this.$nextTick(() => {

            this.$refs.operateTable.store.states.columns.map((column) => {

              if (column.filteredValue && column.filteredValue.length) {

                console.log("!11");

                this.$refs.operateTable.store.commit("filterChange", {

                  column,

                  values: column.filteredValue,

                  silent: true,

                });

              }

            });

          });

        } else {

          this.columns[i].filteredValue = [];

          this.columns[i].defaultValue = "";

        }

      }

      // for (let i = 0; i < this.columns.length; i++) {

      //   if (this.columns[i].label === value) {

      //     this.columns[i].defaultValue = filteredInputValue;

      //   } else {

      //     this.columns[i].defaultValue = "";

      //   }

      // }

      // 如果是有排序的字段,恢复排序

      if (value === this.sort.label) {

        this.$nextTick(() => {

          //在数据加载完,重新渲染表格

          this.isCheckBoxSort = true;

          this.$refs.operateTable.sort(this.sort.prop, this.sort.order);

        });

      }

      */

    },

    // 处理生成columns 的label prop键值对

    normalizeColumnsLabelMap() {

      this.columns.map((column) => {

        this.columnsLabelMap[column.label] = column.prop;

      });

    },

    filterInputMethod(column, inputFilteredMap) {

      console.log("column, inputFilteredMap", column, inputFilteredMap);

      this.inputFilteredMap = inputFilteredMap;

      this.$emit("filterInputMethod", column, inputFilteredMap);

    },

    resetChangeMethod(tableColumn, columnProp) {

      this.$emit("resetChangeMethod", tableColumn, this.inputFilteredMap);

    },

    cellMouseEnter(row, column, cell, event) {

      this.$emit("cell-mouse-enter", row, column, cell, event);

    },

    cellMouseLeave(row, column, cell, event) {

      this.$emit("cell-mouse-leave", row, column, cell, event);

    },

    cellClick(row, column, cell, event) {

      this.$emit("cell-click", row, column, cell, event);

    },

    cellDblclick(row, column, cell, event) {

      this.$emit("cell-dblclick", row, column, cell, event);

    },

    rowClick(row, column, event) {

      this.$emit("row-click", row, column, event);

    },

    rowContextmenu(row, column, event) {

      this.$emit("row-contextmenu", row, column, event);

    },

    rowDblclick(row, column, event) {

      this.$emit("row-dblclick", row, column, event);

    },

    headerClick(column, event) {

      this.$emit("header-click", column, event);

    },

    headerContextmenu(column, event) {

      this.$emit("header-contextmenu", column, event);

    },

    sortChange(sortObj) {

      this.changeSort(sortObj);

      // this.$componentsStore.commit("table/changeSort", sortObj);

      if (!this.isCheckBoxSort) {

        this.$emit("sort-change", sortObj);

      }

      // 还原isCheckBoxSort

      this.isCheckBoxSort = false;

    },

    handleDefaultSort() {

      if (this.options.defaultSort !== undefined) {

        let column = { label: "" };

        // for (let index = 0; index < this.columns.length; index++) {

        //   if (this.columns[index].prop === this.options.defaultSort.prop) {

        //     column.label = this.columns[index].label;

        //     break;

        //   }

        // }

        column.label = this.columnsLabelMap[this.options.defaultSort.prop];

        this.changeSort({

          ...this.options.defaultSort,

          column,

        });

      }

    },

    // 点击操作的下拉项目后触发事件

    handleCommand(command) {

      if (command.method) {

        command.method(command.index, command.row, command.label);

      }

    },

    // 点击dropDown传参方法

    composeValue(item, row, index) {

      return {

        label: item.label,

        row: row,

        index: index,

        method: item.method,

      };

    },

    select(selection, row) {

      this.$emit("select", selection, row);

    },

    selectAll(selection) {

      this.$emit("select-all", selection);

    },

    checkboxSelected(selection) {

      this.$emit("selection-change", selection);

    },

    selectable(row, index) {

      let data = true;

      this.$emit("selectable", row, index, (val) => {

        data = val;

      });

      return data;

    },

    getRowKeys(row) {

      let data;

      for (let index = 0; index < this.dataSource.length; index++) {

        if (row === this.dataSource[index]) {

          data = index;

          break;

        }

      }

      // this.dataSource.map((item, index) => {

      //   if (row === item) {

      //     data = index;

      //   }

      // });

      this.$emit("row-key", row, (val) => {

        data = val;

      });

      return data;

    },

    load(tree, treeNode, resolve) {

      this.$emit("load", tree, treeNode, resolve);

    },

    // 记录表格总的筛选状态,用于列显示隐藏时保存checkbox状态

    filterChange(filters) {

      let currKey = Object.keys(filters)[0];

      if (filters[currKey].length === 0) {

        delete this.checkBoxFilteredMap[currKey];

      } else {

        this.checkBoxFilteredMap[currKey] = filters[currKey];

      }

      this.$emit("filter-change", filters);

    },

    checkChange(nodeObj, checkObj) {

      this.checkedList = checkObj.checkedNodes.map((item) => {

        return item.label;

      });

    },

    // 之前写在vuex里的方法

    changeSort(sort) {

      this.sort.prop = sort.prop;

      this.sort.order = sort.order;

      this.sort.label = sort.column.label;

    },

    saveCheckedList(preCheckedList) {

      this.preCheckedList = preCheckedList;

    },

  },

};

</script>

<style>

    .operateTable{

        position: relative;

        width: 100%;

    }

    .operateTable .column-dropdown{

        position: absolute;

        right: 0px;

        top: -42px;

        z-index: 99;

    }

    .caoz_ft_warp{

      text-align: center;

    }

    .caoz_ft_warp .el-input.is-active .el-input__inner, .caoz_ft_warp .el-input__inner:focus{

        border-color: #9A4B9B;

        outline: 0;

    }

    .el-checkbox__input.is-checked .el-checkbox__inner,.el-checkbox__input.is-indeterminate .el-checkbox__inner {

        background-color: #9a4b9b;

        border-color: #9a4b9b;

    }

    .el-checkbox__inner:hover {

        border-color: #9A4B9B;

    }

    .el-checkbox__input.is-focus .el-checkbox__inner{

        border-color: #9A4B9B;

    }

    .el-checkbox__input.is-checked+.el-checkbox__label {

        color: #9A4B9B;

    }

    .checkboxScorll .el-checkbox__input.is-checked + .el-checkbox__label {

        color: #666;

    }

    .column-dropdown .el-button{margin-right: 0 !important;min-width:0;}

    .column-dropdown .el-button:focus, .el-button:hover{

        color: #9A4B9B;

        border-color: #e1c9e1;

        background-color: #f5edf5;

    }

    .checkboxScorll {

        max-height: 300px;

        overflow-y: auto;

    }

    .checkboxScorll .checkbox {

        display: block;

        margin-top: 10px;

        padding-left: 20px;

    }

</style>

第三步:在页面中引入operateTable并使用

<template>

  <div class="tableView">

    <div class="content">

      <operateTable

        v-loading="loading"

        :dataSource="operateTableData"

        :columns="operateTableColumns"

        :options="operateTableOption"

        :defaultColumn="defaultColumns"

        :totalColumn="totalColumns"

        :defaultSelectedColumn="defaultSelectedColumn"

        @sort-change="sortChange"

        @saveSettingColumns="saveSettingColumns"

      ></operateTable>

    </div>

  </div>

</template>

<script>

import operateTable from "./components/operateTable.vue";

export default {

  name: "",

  components: {

    operateTable,

  },

  data() {

    return {

      loading: false,

      operateTableData: [

        {

          date: "2016-05-02",

          name: "王小虎",

          address: "上海市普陀区金沙江路 1518 弄",

        },

        {

          date: "2016-05-04",

          name: "王小虎",

          address: "上海市普陀区金沙江路 1517 弄",

        },

        {

          date: "2016-05-01",

          name: "王小虎",

          address: "上海市普陀区金沙江路 1519 弄",

        },

        {

          date: "2016-05-03",

          name: "王小虎",

          address: "上海市普陀区金沙江路 1516 弄",

        },

      ],

      operateTableColumns: [

        {

          prop: "action",

          label: "操作",

          width: 100,

          fixed: true,

          render: (h, params) => {

            return h(

              "div",

              {

                class: "operate-group",

              },

              [

                h(

                  "el-tooltip",

                  {

                    props: {

                      content: "处理",

                      placement: "bottom",

                      enterable: false,

                      effect: "light",

                    },

                    class: "item",

                  },

                  [

                    h("i", {

                      props: {},

                      class: "el-icon-edit",

                      on: {

                        click: () => {

                          console.log(params.row);

                        },

                      },

                    }),

                  ]

                ),

              ]

            );

          },

        },

        {

          prop: "date",

          label: "日期",

          minwidth: 150,

          sortable: "custom",

        },

        {

          prop: "name",

          label: "姓名",

          minwidth: 150,

          sortable: "custom",

        },

        {

          prop: "address",

          label: "地址",

          minwidth: 150,

          sortable: "custom",

        },

      ],

      operateTableOption: {

        stripe: true, // 是否为斑马纹 table

        highlightCurrentRow: true, // 是否要高亮当前行

        columnsSelect: true,

        maxHeight: 300,

      },

      defaultColumns: ["操作", "日期", "姓名", "地址"],

      totalColumns: ["操作", "日期", "姓名", "地址"],

      //所有用户默认勾选的列  用于初始化

      defaultSelectedColumn: [],

    };

  },

  methods: {

    //表头排序

    sortChange(column, prop, order) {

      if (column.order === "ascending") {

        this.orderfield = column.prop;

        this.orderby = "ASC";

      } else if (column.order === "descending") {

        this.orderfield = column.prop;

        this.orderby = "DESC";

      } else {

        this.orderfield = "";

        this.orderby = "";

      }

      //   this.getTabldHandle();

    },

    //保存自定义字段

    saveSettingColumns(data) {

      console.log(data);

    },

  },

  mounted() {},

};

</script>

<style>

.tableView {

  width: 100%;

  height: 100%;

}

.content {

  padding: 60px;

}

.disableIcon {

  color: #c0c4cc;

  cursor: not-allowed;

}

</style>

 文章来源地址https://www.toymoban.com/news/detail-787616.html

 

到了这里,关于Vue+Element Ui实现el-table自定义表头下拉选择表头筛选的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包