天天看點

Element table 二次封裝

table 元件封裝心路曆程:多選列為一塊,index列為一塊,中間的後端傳回來的資料為一塊,操作列為一塊.

父元件 通過props 傳 input 還是select 等類型,子元件接收 展示

是以說 table 分為這4個部分.

1.2部分很簡單,多選列,index列 是否展示

第3塊:後端傳回的資料 在table展示

這塊的邏輯分為2種:

(1)單純的資料展示

(2)目前列是否可編輯

<template slot-scope="scope">
   <template v-if="column.formatter">
     <span
       v-html="column.formatter(scope.row, column)"
       @click="clickColumn(scope.row,column)"
     ></span>
   </template>
   <template v-else>
     <span>{{scope.row[column.prop]}}</span>
   </template>
</template>
           

當(2)情況 可在 父元件 formatter()中 寫 html标簽 等操作

第4塊:編輯删除 等功能按鈕,循環接收父元件傳值,功能在父元件實作,子元件隻是點選

<template slot-scope="scope">
          <div class="operate-group">
            <template v-for="(btn, key) in operates.list">
              <span class="item" v-if="btn.show" :key="btn.id">
                <el-button
                  :type="btn.type"
                  size="mini"
                  :icon="btn.icon"
                  @click.native.prevent="btn.method(key,scope.row)"
                >{{ btn.label }}</el-button>
              </span>
            </template>
          </div>
        </template>
           

子元件完整代碼:

<template>
  <div class="tablebar">
    <el-table
      id="ciscoTable"
      :row-key="needExpand?needExpand:null"
      :default-expand-all="options.isExpendAll"
      :height="options.height"
      ref="ciscoTable"
      tooltip-effect="dark"
      :highlight-current-row="options.highlightCurrentRow"
      :header-cell-style="{
          'background-color': '#f5f5f5'
        }"
      border
      v-loading.iTable="options.loading"
      :data="tableDataComputed"
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="options.hasSelect" type="selection" style="width: 55px;"></el-table-column>
      <el-table-column v-if="options.hasIndex" type="index"></el-table-column>
      <template v-for="(column) in columns">
        <el-table-column
          show-overflow-tooltip
          sortable
          :prop="column.prop"
          :key="column.id"
          :label="column.label"
          :align="column.align"
          :width="column.width"
          :min-width="column.minWidth"
        >
          <template slot-scope="scope">
            <template v-if="column.formatter">
              <span
                v-html="column.formatter(scope.row, column)"
                @click="clickColumn(scope.row,column)"
              ></span>
            </template>
            <template v-else>
              <span>{{scope.row[column.prop]}}</span>
            </template>
          </template>
        </el-table-column>
      </template>
      <el-table-column
        ref="fixedColumn"
        label="操作"
        align="left"
        :width="operates.width?operates.width:170"
        :fixed="operates.fixed"
        :min-width="operates.minWidth"
        v-if="options.hasHandle&&isColShow"
      >
        <template slot-scope="scope">
          <div class="operate-group">
            <template v-for="(btn, key) in operates.list">
              <span class="item" v-if="btn.show" :key="btn.id">
                <el-button
                  :type="btn.type"
                  size="mini"
                  :icon="btn.icon"
                  @click.native.prevent="btn.method(key,scope.row)"
                >{{ btn.label }}</el-button>
              </span>
            </template>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
import VU from "../../libs/VUtil";
export default {
  props: {
    list: {
      type: Array,
      default: []
    },
    needExpand: {
      type: String,
      default: null
    },
    columns: {
      type: Array,
      default: []
    },
    operates: {},
    // table 表格的控制參數
    options: {
      type: Object,
      default: {
        highlightCurrentRow: false, // 是否要高亮目前行
        isExpendAll: false //table-tree預設不展開
      }
    },
    filterInput: {
      type: String,
      default: ""
    },
    // l2 右側彈出 操作列 在編輯/添加顯示, 詳情浏覽隐藏
    isColShow: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      inputVal: "",
      tableColumns: [],
      contentHeight: 1
    };
  },
  watch: {
    filterInput: {
      handler(newVal, oldVal) {
        this.inputVal = newVal;
      }
    },
    isColShow: {
      handler(newVal, oldVal) {
        this.isCol = newVal;
      }
    }
  },
  mounted() {
    this.$nextTick(function() {
      this.tableColumns = this.$refs.ciscoTable.columns;
      if (document.querySelector("#pagebar")) {
        VU.resize.autoResizeContent(
          this,
          document.querySelector("#pagebar").offsetHeight
        );
      } else {
        VU.resize.autoResizeContent(this);
      }
    });
  },
  computed: {
    tableDataComputed() {
      if (this.tableColumns.length !== 0 && this.list.length !== 0) {
        return VU.table.filterTableData(
          this.tableColumns,
          this.list,
          this.inputVal
        );
      }
    }
  },
  methods: {
    // 多行選中
    handleSelectionChange(val) {
      this.$emit("handleSelectionChangeFunc", val);
    },
    // 增加接口
    addInterface(val) {
      this.$emit("addInterfaceFunc", val);
    },
    // +子接口
    chooseChildInterface(val) {
      this.$emit("chooseChildInterfaceFunc", val);
    },
    // 選擇
    chooseInterface(val) {
      this.$emit("chooseInterfaceFunc", val);
    },
    //l2 右邊彈窗 詳情
    showDetails(val) {
      this.$emit("showDetailsFunc", val);
    },
    //開啟 暫停服務
    startRow(val) {
      this.$emit("startRowFunc", val);
    },
    // 記錄檔 内容json 展示
    contentShow(val) {
      this.$emit("contentShowFunc", val);
    },
    //點選列 彈窗 或者 各種事件
    clickColumn(row, column) {
      if (column.prop === "lineName") {
        this.showDetails(row);
      } else if (column.prop === "status") {
        this.startRow(row);
      } else if (column.prop === "content") {
        this.contentShow(row);
      }
    }
  }
};
</script>
<style lang="scss" >
.tablebar button i {
  font-size: 13px;
}
</style>
           

父元件prop傳值,邏輯在父元件實作

<lllsj-table
      :list="authgroupData"
      @handleSelectionChangeFunc="handleSelectionChange"
      :options="options"
      :columns="columns"
      :operates="operates"
      :filterInput="filterInput"
    ></lllsj-table>
           
options: {
        loading: false, // 是否添加表格loading加載動畫
        highlightCurrentRow: false, // 是否支援目前行高亮顯示
        hasSelect: true, // 是否支援清單項選中功能
        hasIndex: true, //是否有序号列
        hasHandle: true
      },
      columns: [
        {
          prop: "auth_group_name",
          label: "授權組名稱",
          align: "left"
        },
        {
          prop: "username",
          label: "姓名",
          align: "left"
        },
        {
          prop: "password",
          label: "密碼",
          align: "left"
        },
        {
          prop: "enable_password",
          label: "password",
          align: "left"
        },
        {
          prop: "protocol",
          label: "管理協定",
          align: "left"
        },
        {
          prop: "port",
          label: "端口号",
          align: "left"
        },
        {
          prop: "description",
          label: "描述",
          align: "center"
        },
        {
          prop: "status",
          label: "狀态",
          align: "left",
          formatter: (row, column, cellValue) => {
            if (row.status === "admin down") {
              return `<span style="color:#BC4442;font-weight:bold">admin down</span>`;
            } else if (row.status === "down") {
              return `<span style="color:#BC4442; font-weight:bold">down</span>`;
            } else {
              return `<span style="color:green; font-weight:bold">up</span>`;
            }
          }
        },
      ],
      operates: {
        width: "150px",
        list: [
          {
            id: "1",
            label: "編輯",
            type: "text",
            show: true,
            icon: "el-icon-edit",
            method: (index, row) => {
              this.editRow(row);
            }
          },
          {
            id: "2",
            label: "删除",
            type: "text",
            icon: "el-icon-delete",
            show: true,
            method: (index, row) => {
              this.deleteRow(row);
            }
          }
        ]
      }
           
Element table 二次封裝