关于el-table二次封装插槽slot的问题?

先看下面我的el-table二次封装相关代码。

index.vue

<el-table
  ref="table"
  v-loading="searching"
  :data="pagedData"
  :border="border"
  stripe
  highlight-current-row
  v-bind="$attrs"
  v-on="$listeners"
  @selection-change="handleSelectionChange"
>
  <template v-for="(item, index) in columnList">
    <el-table-column
      v-if="item.slotScope"
      :key="item.prop + index"
      v-bind="item"
      :label="$t(item.label)"
    >
      <template slot-scope="scope">
        <slot
          :name="item.prop"
          v-bind="scope"
        >
          {{ "-" }}
        </slot>
      </template>
    </el-table-column>
    <el-table-column
      v-else-if="item.selection"
      :key="`selection${index}`"
      type="selection"
      :width="item.width || 50"
      :align="item.align || 'center'"
    />
    <column
      v-else
      :key="item.prop + index"
      :column="item"
    />
  </template>
</el-table>

column.vue

<template>
  <el-table-column
    center
    v-bind="column"
    v-on="$listeners"
    :label="$t(column.label)"
  >
    <!-- <template
      slot="header"
      slot-scope="scope"
    >
      <render
        v-if="column.renderHeader"
        :scope="scope"
        :render="column.renderHeader"
      />
      <span v-else>{{ scope.column.label }}</span>
    </template> -->

    <template slot-scope="scope">
      <render
        v-if="column.render"
        :scope="scope"
        :render="column.render"
      />

      <!-- 嵌套表格 -->
      <template v-else-if="column.children">
        <column
          v-for="col in column.children"
          :key="col.prop"
          :column="col"
        />
      </template>
    </template>
  </el-table-column>
</template>

然后在页面中使用:

<EleTable
  id="eleTable"
  ref="eleTable"
  :row-key="getRowKeys"
  :column-list="columnList"
  :remote-method="getTableData"
  @page-change="handlePageChange"
  @sort-change="handleSortChange"
  @selection-change="handleSelectionChange"
>
  <template v-slot:vip_state="{ row }">
    <span>{{ filterVal('vip_state', row.vip_state) }}</span>
  </template>
  <template v-slot:appeal_type="{ row }">
    <span>{{ filterCasVal('appeal_type',row.appeal_type) }}</span>
  </template>
  <template v-slot:priority="{ row }">
    <span>{{ filterVal('priority',row.priority) }}</span>
  </template>
  <template v-slot:appeal_stage="{ row }">
    <span>{{ filterVal('appeal_stage',row.appeal_stage) }}</span>
  </template>
  <template v-slot:maintain_mode="{ row }">
    <span>{{ filterVal('maintain_mode',row.maintain_mode) }}</span>
  </template>
  <template v-slot:language="{ row }">
    <span>{{ filterVal('lang',row.language) }}</span>
  </template>
  <template v-slot:comment_counter="{ row }">
    <span>{{ filterComment(row.comment_counter) }}</span>
  </template>
  <template v-slot:task_id="{ row }">
      <span>{{ row.task_id }}</span>
    <el-badge class="task-badge" :value="row.over_process ? $t('text_overtime') : ''">
    </el-badge>
  </template>
</EleTable>

但是这样使用中间会有很多插槽,而且插槽内还有一些过滤方法,感觉封装还是没有减少代码量,一时不知道该如何解决这种情况,希望大家帮我出出主意。

阅读 4.3k
2 个回答
    <el-table :data="data" :height="height" :stripe="stripe" :row-key="rowKey" :tree-props="{children: 'child', hasChildren: 'hasChildren'}"
      @selection-change="handleSelectionChange">
      <!--自定义空行-->
      <empty-view slot="empty-text" text="暂无数据" />
      <!--判断是否开启多选-->
      <el-table-column v-if="isSelection" type="selection" align="right" width="60px" :selectable='selectEnable' />
      <el-table-column v-if="isExpend" type="expand" align="left" width="60px">
        <template v-slot:default="scope">
          <slot name="expend" :$index="scope.$index" :row="scope.row"></slot>
        </template>
      </el-table-column>
      <template v-for="column in columns">
        <!--序号列-->
        <el-table-column v-if="column.type === 'index'" type="index" :label="column.title || '序号'" :align="column.align || 'left'" :width="column.width || '65px'"
          :index="column.tableIndex || tableIndex" />
        <!--操作列-->
        <el-table-column v-else-if="column.type === 'action'" :label="column.title" :align="column.align || 'left'" :width="column.width || 180" :fixed="column.fixed || 'right'">
          <template slot-scope="scope">
            <template v-for="(action, actIdx) in column.actions">
              <template v-if="actIdx < (column.maxNum || 2)">
                <a :class="`action-btn ${action.class || ''}`" v-if="scope.row['btnShow'] || true" v-has="action.permission"
                  @click="actionClick(scope.row, action.fun)">{{ action.title }}</a>
              </template>
            </template>
            <template v-if="column.actions.length >= (column.maxNum || 2)">
              <el-dropdown trigger="click" class="action-more-line" @command="(command) =>{actionClick(scope.row,command)}">
                <span class="el-dropdown-link">
                  更多<i class="el-icon-arrow-down el-icon--right"></i>
                </span>
                <el-dropdown-menu slot="dropdown">
                  <template v-for="(action, actIdx) in column.actions">
                    <template v-if="actIdx >= (column.maxNum || 2)">
                      <el-dropdown-item :command="action.fun">{{ action.title }}</el-dropdown-item>
                    </template>
                  </template>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
          </template>
        </el-table-column>
        <!--多表头-->
        <el-table-column v-else-if="column.child && column.child.length > 0" :label="column.title" :align="column.align || 'left'">
          <template v-for="col in column.child">
            <el-table-column :label="col.title" :align="col.align || 'left'" :resizable="col.resize || false" :min-width="col.width" :fixed="col.fixed || false">
              <template slot-scope="scope">
                <slot v-if="col.slot" :name="col.prop" :row="scope.row" />
                <span v-else :style="{color: ''}">{{
                    (scope.row[col.prop] || scope.row[col.prop] == 0) ? scope.row[col.prop] : '-'
                  }}</span>
              </template>
            </el-table-column>
          </template>
        </el-table-column>
        <!--自定义列、常规列-->
        <el-table-column v-else :label="column.title" :align="column.align || 'left'" :resizable="column.resize || false" :min-width="column.width" :fixed="column.fixed || false">
          <template slot-scope="scope">
            <slot v-if="column.slot" :name="column.prop" :row="scope.row" :$index="scope.$index" />
            <span v-else-if="column.filter">{{scope.row[column.prop]|filterVal(column.arr)}}</span>
            <span v-else :style="{color: ''}">{{
                (scope.row[column.prop] || scope.row[column.prop] == 0) ? scope.row[column.prop] : '-'
              }}</span>
          </template>
        </el-table-column>
      </template>
    </el-table>

你看看,我这个封装

既然这样的情况你封装 table 组件的目的是什么呢呢😂。
不应该传入一个 columns 属性,让你封装的 table 组件按照你传入的表头生成列和自定义 render 方法吗。可以借鉴 AntD VueTable 组件的实现 👉 Table - Ant Design Vue

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题