1. 程式人生 > 程式設計 >解決ant design vue 表格a-table二次封裝,slots渲染的問題

解決ant design vue 表格a-table二次封裝,slots渲染的問題

目的就是對a-table進行二次封裝,但是在如何顯示a-table的slot時遇到了問題,原本想法是在a-table內把$slots都渲染,期望在使用該元件時能正確渲染,然而。。。並不會正確渲染

<template>
 <a-table
  bordered
  :scroll="{ x: scrollX,y: 600 }"
  v-bind="{...$attrs,...$props,...{dataSource: body,columns: header}}"
  :loading="loadingObj"
  v-on="listeners"
 >
  <template v-for="(val,slot) in $slots" :slot="slot">{{ this.$slots[slot] }}</template>
 </a-table>
</template>

後來,在某個寫法裡找到了a-table有scopedSlots這個引數,但是在template裡直接賦值也不行,如下

<a-table
  bordered
  :scroll="{ x: scrollX,columns: header}}"
  :loading="loadingObj"
  v-on="listeners"
  :scopedSlots="$scopedSlots"
 >

可行方法

元件不採用template寫,用render()

則變成:

render () {
  const on = {
   ...this.$listeners
  }
  const props = { ...this.$attrs,...this.$props,...{ dataSource: this.body,columns: this.header }}
  const table = (
   <a-table bordered props={props} scopedSlots={ this.$scopedSlots } on={on}>
   </a-table>
  )
  return (
   <div class="dc-table">
    { table }
   </div>
  )
 },methods: () {
 
}

重點在於scopedSlots={ this.$scopedSlots }, 這樣在使用元件的外部直接寫slot就可以正常渲染

呼叫方法

<dc-table
   ref="table"
   :columns="header"
   :dataSource="body"
   :loading="loading"
   :pagination="pagination"
   @change="handleTableChange"
   class="table-fit"
  >
 
    // 這裡是表頭的渲染,下面會講到
   <template v-for="title in headerSlots" :slot="'$' + title">
    <span :key="title">
     <a-tooltip placement="right" trigger="click">
      <template slot="title">{{ getHeaderTarget(title).remark }}</template>{{ getHeaderTarget(title).title }}<a-icon type="info-circle"/>
     </a-tooltip>
    </span>
   </template>
  // 這裡渲染列資料
   <template v-for="(item,index) in DECIMAL_PARAMS" :slot="item" slot-scope="text">
    <span :key="index">
     <!-- <span v-if="item === 'estimated_ROI'">
      <template v-if="text === 0">{{ text }}</template>
      <template v-else>{{ (text * 100) | NumberFixed }}%</template>
     </span> -->
     <span>{{ text | NumberFixed | NumberFormat }}</span>
    </span>
   </template>
  </dc-table>

如下表格資料原本是資料,渲染成逢三斷一,並2位小數

解決ant design vue 表格a-table二次封裝,slots渲染的問題

this.$scopedSlots資料格式:

解決ant design vue 表格a-table二次封裝,slots渲染的問題

在header中為scopedSlots: {customRender: 'consumption'} 格式

表頭slot如何渲染

還是同一個表格,要求表頭有提示資訊,所以我在表頭也做了slots渲染了a-tooltip顯示提示資訊

此時header格式為

[{scopedSlots: {customRender: 'consumption',title: '$consumption'} }]

表頭渲染設定scopedSlots裡title欄位,名字自定義

此時的this.$scopedSlots也有$consumption表頭slot欄位,但是並不能正常渲染出來

解決ant design vue 表格a-table二次封裝,slots渲染的問題

但是發現this.$slots裡有且只有表頭的slot

解決ant design vue 表格a-table二次封裝,slots渲染的問題

此時我覺得,我應該把$slots的內容渲染在a-table裡,則

 render () {
  const on = {
   ...this.$listeners
  }
  const props = { ...this.$attrs,columns: this.header }}
  // slots迴圈
  const slots = Object.keys(this.$slots).map(slot => {
   return (
    <template slot={slot}>{ this.$slots[slot] }</template>
   )
  })
  const table = (
   <a-table bordered props={props} scopedSlots={ this.$scopedSlots } on={on}>
    {slots} // 放這裡
   </a-table>
  )
  return (
   <div class="dc-table">
    { table }
   </div>
  )
 },

大功告成!

補充知識:Ant Design of Vue中 的a-table一些使用問題

1.新增行點選及複選框

<template>
 <div>
  <a-table
   :rowSelection="{selectedRowKeys: selectedRowKeys,onChange: onSelectChange}"
   :columns="columns"
   :dataSource="data"
   :customRow="onClickRow"
  />
 </div>
</template>
<script>
 const columns = [
  {
   title: 'Name',dataIndex: 'name',},{
   title: 'Age',dataIndex: 'age',{
   title: 'Address',dataIndex: 'address',];

 const data = [];
 for (let i = 0; i < 46; i++) {
  data.push({
   key: i,name: `Edward King ${i}`,age: 32,address: `London,Park Lane no. ${i}`,});
 }

 export default {
  data() {
   return {
    data,columns,selectedRowKeys: [],// Check here to configure the default column
    selectedRows: [] // 選中的整行資料
    loading: false,};
  },methods: {
   onSelectChange (selectedRowKeys,selectedRows) {
    this.selectedRowKeys = selectedRowKeys;
    this.selectedRows = selectedRows
   },onClickRow (record) {
    return {
     on: {
      click: () => {
       const rowKeys = this.selectedRowKeys
       const rows = this.selectedRows
       if (rowKeys.length > 0 && rowKeys.includes(record.key)) {
        rowKeys.splice(rowKeys.indexOf(record.key),1)
        rows.splice(rowKeys.indexOf(record.key),1)
       } else {
        rowKeys.push(record.key)
        rows.push(record)
       }
       this.selectedRowKeys = rowKeys
       this.selectedRows = rows
      }
     }
    }
   }
  },};
</script>

2.固定列重疊問題

官方給的建議

對於列數很多的資料,可以固定前後的列,橫向滾動檢視其它資料,需要和 scroll.x 配合使用。

若列頭與內容不對齊或出現列重複,請指定固定列的寬度 width。

建議指定 scroll.x 為大於表格寬度的固定值或百分比。注意,且非固定列寬度之和不要超過 scroll.x。

const columns = [
  { title: 'Full Name',width: 100,key: 'name',fixed: 'left' },{ title: 'Age',key: 'age',{ title: 'Column 1',key: '1' },{ title: 'Column 2',key: '2' },{ title: 'Column 3',key: '3' },{ title: 'Column 4',key: '4' },{ title: 'Column 5',key: '5' },{ title: 'Column 6',key: '6' },{ title: 'Column 7',key: '7' },{ title: 'Column 8',key: '8' },{
   title: 'Action',key: 'operation',fixed: 'right',scopedSlots: { customRender: 'action' },];

我在專案中為其他列新增width,scroll x設定為這些width之和,新增一個空列,讓這列自適應寬度

{
 title: ''
},

3.縱向滾動條(表格高度隨螢幕高度改變而改變)

<a-table
  :scroll={y: scrollY}
   :rowSelection="{selectedRowKeys: selectedRowKeys,onChange: onSelectChange}"
   :columns="columns"
   :dataSource="data"
   :customRow="onClickRow"
  />
data(){
 return {
 scrollY: document.body.clientHeight - 386,// 表格豎向滾動條,386是頁面其他元素的高度
 screenHeight: document.body.clientHeight,// 螢幕的高度
 }
} 

watch: {
  // 監聽螢幕高度改變表格高度
  screenHeight (val) {
   // 初始化表格高度
   this.scrollY = val - 386
  }

 },mounted () {
  // 監聽螢幕高度
  window.onresize = () => {
   return (() => {
    window.screenHeight = document.body.clientHeight
    this.screenHeight = window.screenHeight
   })()
  }
 },

以上這篇解決ant design vue 表格a-table二次封裝,slots渲染的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。