SoFunction
Updated on 2025-03-08

vue elementui secondary packaging el-table with slot problem

Elementui secondary packaging el-table with slot

Subcomponent table encapsulation html part

<template>
  <div
    v-loading="loading">
    <el-table
      ref="tableData"
      :stripe="stripe"
      :height="height"
      :max-height="maxHeight"
      header-row-class-name="table-list-header"
      row-class-name="table-list-row"
      :size="tableSize"
      :data="data"
      @selection-change="handleSelectionChange"
      @current-change="handleTableCurrentChange"
      @row-click="handleTableRowClick"
      v-bind="otherConfig">
      <template v-for="(p, index) in columns">
        <!-- Select box -->
        <el-table-column
          v-if=""
          type="selection"
          width=" ?  : 50"
          :fixed=""
          align="center"
          :key="index"
        ></el-table-column>
        <!-- Serial number -->
        <el-table-column
          v-else-if=""
          type="index"
          width=" ?  : 80"
          label="Serial Number"
          :index=""
          :key="index"
        ></el-table-column>
        <!-- Multi-level header -->
        <el-table-column
          v-else-if=""
          align="center"
          :label=""
          :key="index"
        >
          <el-table-column
            v-for="(child, childIndex) in "
            :key="childIndex"
            v-bind="child"
          >
          </el-table-column>
        </el-table-column>
        <!-- Custom content -->
        <el-table-column
         v-else-if=""
         :label=""
         :key="index">
        <slot
          :name=""
          :fixed=""></slot>
        </el-table-column>
        <!-- General fields -->
        <el-table-column
          v-else
          :prop=""
          :width=""
          :label=""
          :key="index"
        ></el-table-column>
      </template>
    </el-table>
    <!-- eslint-disable -->
    <el-pagination
      v-if="isPaginationShow && "
      class="opagination mt12"
      background
      layout="sizes, prev, pager, next"
      :page-sizes="[10, 20, 50, 100]"
      :=""
      :page-size=""
      :total=""
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    >
    </el-pagination>
  </div>
</template>

js part

<script>
export default {
  name: 'AppTable',
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    data: {
      type: Array,
      default: () => []
    },
    pagination: {
      type: Object,
      default: () => ({})
    },
    isPaginationShow: {
      type: Boolean,
      default: true
    },
    tableSize: {
      type: String,
      default: 'small'
    },
    stripe: {
      type: Boolean,
      default: true
    },
    otherConfig: {
      type: Object,
      default: () => {}
    },
    loading: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {}
  },
  methods: {
    // Switch page numbers    handleCurrentChange () {
      this.$emit('getData')
    },
    // Switch the number of bars per page    handleSizeChange (value) {
      // Both current-page and page-size support .sync modifier. If you use the .sync modifier, you do not need to manually assign values ​​to       = value
      this.$emit('getData')
    },
    // Switch selection    handleSelectionChange (val) {
      this.$emit('changeSelection', val)
    },
    // Single choice    handleTableCurrentChange (currentRow) {
      this.$emit('changeCurrent', currentRow)
    },
    // Click on Line    handleTableRowClick (currentRow) {
      this.$emit('rowClick', currentRow)
    }
  },
  watch: {
    data () {
      // Table scrolls to top when re-requesting data      this.$.$ = 0
    }
  }
}
</script>

Using html code in parent component

<template>
  <div class="hello">
   <app-table
      :columns="columns"
      :data="tableList"
      :pagination="pagination"
      @getData="fetchTableList"
      :loading="loading"
   >
        <template slot="action"
          slot-scope="scope">
          <el-button
            type="text"
            @click="showDetail()">check the details</el-button>
        </template>
   </app-table>
  </div>
</template>

js code part

<script>
// Introduce subcomponent formimport AppTable from '@/components/'
export default {
  name: 'HelloWorld',
  components: { AppTable },
  data () {
    return {
      loading: false,
      columns: [
        { selection: true },
        { type: 'index' },
        {prop: 'name', label: 'name', width: 160},
        { slot: 'action', label: 'operate' }
      ],
      tableList: [{}],
      pagination: {
        current: 1,
        size: 10,
        total: 100
      }
    }
  },
  methods: {
    fetchTableList () {
    // Trigger form data request during paging    ()
    }
  }
}
</script>

All basic uses here can be met, including table columns: custom slots; table selectors; table serial numbers and rendering of multi-level table headers.

General styles are generally written according to customized formats. Generally speaking, the basic format of the table is the same. There may also be cases where the table header rows of the table are high and the table rows are high and the contents of the table are different. They can also be handled through configuration parameters.

Secondary package of element-ui table component (slot form)

Due to business needs, the el-table component is secondary encapsulated. The packaging is divided into two layers, the two components are nested and can also be used separately

The simple JS logic processing for the reason is not posted

1. Outer table component packaging

<el-row :gutter="0">
        <el-col :span="12">
          <all-titlebox :msg="tableViewMsg" type="lable_b"></all-titlebox>
        </el-col>
        <el-col :span="12" class="all-t-r btn-box">
          <el-button size="medium" v-if="showAddButton" @click="addData()"
            >New</el-button
          >
          <slot name="topOperation"></slot>
          <all-dropdownsetting
            v-if="showDropdownsetting"
            :list="checkList"
            :colums="showColums"
            @checkedChange="checkedChange($event)"
          ></all-dropdownsetting>
        </el-col>
      </el-row>
      <!-- Operation bar start -->
      <!-- Dividing line start -->
      <el-row :gutter="0">
        <el-col :span="24" class="all-m-t-10">
          <div class="all-primary-line"></div>
        </el-col>
      </el-row>
      <!-- Dividing line end -->
      <el-row :gutter="0">
        <el-col :span="24" class="table-main">
          <itl-table ref="table" :colums="colums" :tableData="tableData" :operationData="operationData" v-bind="$attrs" v-on="$listeners">
            <template v-if="$" v-slot:operation="props">
              <slot name="operation" v-bind="props"></slot>
            </template>
            <template v-for="item in colums" v-slot:[]="props">
              <slot :name="" v-bind="props"></slot>
            </template>
          </itl-table>
        </el-col>
      </el-row>

The core code is this section, which displays fields that require special processing through the form of slots.

 <template v-for="item in colums" v-slot:[]="props">
   <slot :name="" v-bind="props"></slot>
 </template>

Example of using table-view for outer component

&lt;table-view
      table-view-msg="Contract Template Management"
      ref="table-view"
      :table-colums="tableColums"
      :table-data="table"
      add-router="/contract/contrac-template/template-edit"
      :selection='true'
      :showAllSelect="false"
      @view="viewDetail($event)"
      @edit="editData($event)"
      @del="deleteData($event)"
      @page-change="currentChange($event)"
      @size-change="sizeChange($event)"
      :total="total"
      :filter-page-sizes="filterPageSizes"
    &gt;
      &lt;div slot="template-type" slot-scope="{ row }"&gt;
        {{ getType() }}
      &lt;/div&gt;
      &lt;div slot="template-status" slot-scope="{ row }"&gt;
        {{ getStatus() }}
      &lt;/div&gt;
      &lt;!--operationSlot usage example --&gt;
      &lt;!-- &lt;div slot="operation" slot-scope="{ row }"&gt;
        &lt;el-button
          type="text"
          size="small"
          &gt;{{}}&lt;/el-button
        &gt;
      &lt;/div&gt; --&gt;
    &lt;/table-view&gt;

2. Inner table component code

&lt;!-- Basic table components --&gt;
    &lt;div class="ITL-table"&gt;
      &lt;el-row :gutter="0"&gt;
        &lt;el-col :span="24" class="all-m-t-20 table-main"&gt;
          &lt;!-- Table area start --&gt;
          &lt;el-table
            ref="table"
            :data="tableData"
            :stripe="true"
            tooltip-effect="light"
            highlight-current-row
            :header-cell-class-name="cellClass"
            v-bind="$attrs"
            v-on="$listeners"
            @row-click="handleRowClick"
          &gt;
            &lt;el-table-column
              type="selection"
              :width="55"
              v-if="selection"
            /&gt;
            &lt;el-table-column
              type="index"
              :width=" || 'auto'"
              :label=""
              v-if=""
            /&gt;
            &lt;el-table-column
              v-for="item in colums"
              :key=""
              :label=""
              :align=" || 'left'"
              :width=" || 'auto'"
              :min-width=" ?  : minWidth"
              :fixed=" || false"
              :show-overflow-tooltip="
                 === undefined ? tooltip : 
              "
              :formatter=""
              :type=""
            &gt;
              &lt;template slot-scope="{ row, $index }"&gt;
                &lt;span v-if=""&gt;{{ (row, dictList) }}&lt;/span&gt;
                &lt;slot v-else-if="" :name="" :row="row" :index='$index' /&gt;
                &lt;span v-else&gt;{{ row[] }}&lt;/span&gt;
              &lt;/template&gt;
            &lt;/el-table-column&gt;
            &lt;el-table-column
              v-if="(operationData).length || $ || $"
              label="operate"
              :width="operationWidth"
              align="center"
              :fixed="operationFixed"
            &gt;
              &lt;div class="operation-row" slot-scope="scope"&gt;
                &lt;el-button
                  size="small"
                  type="text"
                  v-if=" &amp;&amp; "
                  @click="edit(scope)"
                  &gt;{{  || 'edit' }}&lt;/el-button
                &gt;
                &lt;el-button
                  type="text"
                  size="small"
                  v-if=" &amp;&amp; "
                  @click="view(scope)"
                  &gt;{{  || 'Check' }}&lt;/el-button
                &gt;
                &lt;el-button
                  type="text"
                  size="small"
                  v-if=" &amp;&amp; "
                  @click="del(scope)"
                  &gt;{{  || 'delete' }}&lt;/el-button
                &gt;
                &lt;slot name="operation" :row="" :index="scope.$index"&gt;&lt;/slot&gt;
              &lt;/div&gt;
            &lt;/el-table-column&gt;
          &lt;/el-table&gt;
          &lt;!-- Table area end --&gt;
          &lt;!-- Pagination area start --&gt;
          &lt;div class="pagination all-t-r all-m-t-10" v-if="paginationShow"&gt;
            &lt;el-pagination
              :=""
              :page-sizes="pageSizes"
              :=""
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @current-change="$currentChange($event)"
              @size-change="$sizeChange($event)"
            &gt;
            &lt;/el-pagination&gt;
          &lt;/div&gt;
          &lt;!-- Pagination area end --&gt;
        &lt;/el-col&gt;
      &lt;/el-row&gt;
    &lt;/div&gt;

Inner component itl-table usage example

  <itl-table ref="resumeTable" :paginationShow="false" @view="sendResume" :noHandleRowClick="true" :colums="colums" :tableData="resumeList" @selection-change="onSingleSelection" :showAllSelect="false" :operationData="operationData" :serialNumber="{show:false}" :selection="true">
   <span slot="orgName" class="selectRow" slot-scope="scope" @click="getCompanyIntroduciton()">
       <span>{{  }}</span>
   </span>
   <span slot="postName" class="selectRow" slot-scope="scope"         @click="announceClick()">
      <el-tooltip effect="light" placement="top">
          <div slot="content" v-html=""></div>
              <span>{{  }}</span>
       </el-tooltip>
    </span>
 </itl-table>

The above is personal experience. I hope you can give you a reference and I hope you can support me more.