優雅的使用 element-ui 中的 table 組件

常常使用 element-ui 的小夥伴應該對 el-table 組件很是熟悉,一般它長下面這個樣子:vue

<template>
  <el-table :data="tableData">
    <el-table-column
      prop="date"
      label="日期">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名">
    </el-table-column>
    <el-table-column
      prop="address"
      label="地址">
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  data () {
    return {
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1517 弄'
      }]
    }
  }
}
</script>複製代碼

上面代碼很是正確,但總覺的少了點什麼?element-ui

沒錯,模版中 el-table-column 幾乎一致,重複寫了數組

使用 v-for 來優化模版中的 el-table-column

下面是採用 v-for 的版本,將每一列做爲一個配置項傳入:bash

<template>
  <el-table :data="tableData">
    <el-table-column
      v-for="{ prop, label } in colConfigs"
      :key="prop"
      :prop="prop"
      :label="label">
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  data () {
    this.colConfigs = [
      { prop: 'date', label: '日期' },
      { prop: 'name', label: '姓名' },
      { prop: 'address', label: '地址' }
    ]
    return {
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1517 弄'
      }]
    }
  }
}
</script>複製代碼

這樣作的好處在於,若是想再增長一列,徹底能夠不用動 template,只須要簡單的在 this.colConfigs 這個數組中增長一個配置項 { prop: 'xxx', label: 'xxx' } 便可優化

雖然這樣加個配置很是簡單,擴展性也比以前直接寫模版好,可是若是我有一列是要渲染幾個按鈕,上面的方式就不起做用了ui

換句話說,咱們即想要簡單的屬性能夠直接加個配置項渲染出來,又但願複雜的渲染能在模版中寫出來,要怎麼實現呢?this

巧用 slot,爲 el-table 封裝一層

咱們先來看一下封裝的組件 my-tablespa

// my-table.vue
<template>
  <el-table :data="data">
    <template v-for="colConfig in colConfigs">
      <slot v-if="colConfig.slot" :name="colConfig.slot">
      <el-table-column v-bind="colConfig"></el-table-column>
    </template>  
  </el-table>
</template>

<script>
export default {
  props: ['colConfigs', 'data']
}
</script>複製代碼

這個封裝實際上就是把前面的 colConfigs 做爲一個 prop 傳入,可是跟上面例子有一點不一樣的是,配置項中多了一個 slot 屬性,經過這個屬性,咱們就能夠像文章最開始那樣在模版中寫了,用法以下:.net

<template>
  <my-table
    :data="tableData"
    :col-configs="colConfigs">
    <!-- slot="opt" 不能省略,須要與下面配置項中的對應 -->
    <el-table-column slot="opt">
      <el-button size="mini" slot-scope="{ row }">查看</el-button>
    </el-table-column>
  </my-table>
</template>

<script>
export default {
  data () {
    this.colConfigs = [
      { prop: 'date', label: '日期' },
      { prop: 'name', label: '姓名' },
      { prop: 'address', label: '地址' },
      // 模版中的元素須要對應的有 slot="opt" 屬性
      { slot: 'opt' }
    ]
    return {
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1517 弄'
      }]
    }
  }
}
</script>複製代碼

如今咱們想要增長一個列,只要加個配置項,或者加個 slot ,完美~code

等等,假設個人 table 中有幾列渲染比較複雜,那幾列又都比較類似,像下面這種:

<template>
  <my-table
    :data="tableData"
    :col-configs="colConfigs">
    <el-table-column label="變化" slot="change">
      <span :slot-scope="row">
        {{ row['change'] > 0 ? '+' + row['change']: row['change'] }}
      </span>
    </el-table-column>
    <el-table-column label="趨勢" slot="trend">
      <span :slot-scope="row">
        {{ row['trend'] > 0 ? '+' + row['trend']: row['trend'] }}
      </span>
    </el-table-column>
  </my-table>
</template>複製代碼

又重複寫模版了...

使用 :is="component"

咱們能夠爲配置項再增長一個屬性 component, 用戶能夠指定 component 屬性來特殊處理某列,實現以下:

// my-table.vue
<template>
  <el-table :data="data">
    <template v-for="colConfig in colConfigs">
      <slot v-if="colConfig.slot" :name="colConfig.slot">
      <component
        v-else-if="colConfig.component"
        :is="config.component" 
        :col-config="colConfig">
      </component>
      <el-table-column v-else v-bind="colConfig"></el-table-column>
    </template>  
  </el-table>
</template>

<script>
export default {
  props: ['colConfigs', 'data']
}
</script>複製代碼

而後上面的例子就能夠改寫成:

<template>
  <my-table
    :data="tableData"
    :col-configs="colConfigs">
  </my-table>
</template>
<script>

const PrefixPlusText = {
  props: ['colConfig'],
  template: `
    <el-table-column :label="colConfig.label">
      <span :slot-scope="{ row }">
        {{ parseInt(row[colConfig.prop]) > 0 ? '+' + row[colConfig.prop] : row[colConfig.prop] }}
      </span>
    </el-table-column>
  `
}

export default {
  data () {
    this.colConfigs = [
      { prop: 'change', label: '變化' component: PrefixPlusText },
      { prop: 'name', label: '趨勢', component: PrefixPlusText },
    ]
    return {
      tableData: [{
        change: '12%',
        trend: '10% }, { change: '-12%', trend: '-10%' }] } } } </script>複製代碼

總結

table 做爲數據展現組件,在平常開發中常常被用到,經過這篇文章,能夠看到結合 vueslot/component 特性,作一層封裝,能夠大大簡化 table 的使用,大部分時候只需寫一個配置屬性就能夠了。

最後給一個小 demo

相關文章
相關標籤/搜索