基于Ant Design Vue二次封装表格

本文对Ant Design Vue的表格进行二次封装,通过动态参数配置表格,表格每一列的内容可以由自己设定,例如:标签、操作、链接等,表格还可以自动请求接口获取数据。可以在多个页面重复使用。本文着重阐述对的表格封装,对于下载Ant Design Vue库、按需引入等不进行阐述。

 封装表格

在src创建components/BaseTable/index.vue

<template>
    <a-table
        :columns="columns" //表格配置项
        :data-source="datas" // 表格数据源
        :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }" //表格单选、多选
        :rowKey="(record) => record.key"  //表格行 key 的取值
        :pagination="false" //是否自带分页
    >
    
    // 配置表格头
      <template #headerCell="{ column }">
      //动态配置表格头内容,可以换成其他,只要把span标签的内容换一下即可,可以换成插槽slot
        <template v-if="column.key === 'name'">
          <span>
            Name公司发给粉丝
          </span>
        </template>
      </template>
      
    // 配置表格体内容
      <template #bodyCell="{ column, record }">
        //动态配置链接
        <template v-if="column.key === 'name'">
          <a>
            {
   
   { record.name }}
          </a>
        </template>
        
        //动态配置标签
        <template v-else-if="column.key === 'tags'">
          <span>
            <a-tag
                v-for="tag in record.tags"
                :key="tag"
                :color="tag === 'loser' ? 'volcano' : tag.length > 5 ? 'geekblue' : 'green'"
            >
              {
   
   { tag.toUpperCase() }}
            </a-tag>
          </span>
        </template>
        
       // 配置操作内容,通过插槽动态配置
        <template v-else-if="column.key === 'action'">
          <slot name='tableBtns' :row='record'></slot>
        </template>
        
        // 以下还可以继续配置其他内容,根据每个人的业务场景即可。
      </template>
    </a-table>
    
    // 分页内容
    <div>
      <span>共{
   
   {datas.length}}条数据</span>
      <a-pagination
          v-model:current="current"
          :total="500"
          showQuickJumper
      />
    </div>
</template>


<script setup>
import { usePageReq } from './hook'

const current = ref(1)
const selectedRowKeys = ref([])
const onSelectChange = (key, row) => {
  console.log(key, row)
}

const props = defineProps({
  // 表格配置项
  columns: {
    type: Array,
    default: () => []
  },
  // 请求的接口
  api: {
    type: Function,
    default: () => { }
  },
  // 接口参数
  apiParams: {
    type: Object,
    default: () => ({})
  },
  // 表格X轴的滚动距离
  scrollX: {
    type: Number,
    default: 2500
  },
  // 表格Y轴的滚动距离
  scrollY: {
    type: Number,
    default: 450
  },
})

const { 
    datas,
    pageNumber,
    pageSize
} = usePageReq(props.api, props.apiParams)

</script>

在src创建components/BaseTable/hook.js

import { ref, reactive, toRefs, watch } from 'vue'

export const usePageReq = (api, otherParams) => {
// 分页的页数和一页的大小
    const pageParams = reactive({
        pageNumber: 1,
        pageSize: 10
    })
    const datas = ref([])

    const getPage = () => {
        let apiOtherParams = {}
        
        // 处理传过来的参数
        Object.keys(otherParams).forEach(key => {
            let targeParams = otherParams[key]
            if(typeof targeParams === 'object') {
                Object.assign(apiOtherParams, targeParams)
            } else {
                // 日期参数date的话,而且数组说明是dateRange,参数才分为start和end, date:[]
                if(key === 'date' && Array.isArray(targeParams)) {
                    apiOtherParams['start'] = targeParams[0]
                    apiOtherParams['end'] = targeParams[1]
                } else {
                    apiOtherParams[key] = targeParams
                }
            }
        })

        // 发起请求即可。
        reqFn({
        //请求参数,这里取决于你的接口需要什么参数
            ...apiOtherParams,
            ...pageParams
        }).then(res=> {
        // 这里接收你的请求结果,有什么数据需要获取都写在这里
            datas.value = res.data.content
        })
    }

    watch(() => pageParams.pageNumber, (newVal) => {
        getPage()
    })

    watch(() => pageParams.pageSize, (newVal) => {
        getPage()
    })

    // 刷新表格再次请求
    const search = () => {
        pageParams.pageNumber = 1
        getPage()
    }

// 对外面返回你的参数,想返回什么写什么
    return {
        datas
        ...toRefs(pageParams),
        getPage,
        search
    }
}

我请求后获取的参数为:

//res.data.content对象里面的key值必须和下面columns里面dataIndex的值相同。
//例如这里的department必须和下面columns的dataIndex: 'department'一样。
res.data.content = [
    {
        peoName: 'a',
        department: 'aaa'
    },
     {
        peoName: 'b',
        department: 'bbb'
    },
]

使用封装后的表格

<BaseTable 
           :columns="columns"
           :api="getCrossMonthApi"
           :apiParams="employeeFilterFormData"
           >

  <template #tableBtns="{ row }">
    <div>
      <a-button type="link"
                @click="edit(row)">编辑</a-button>
      <a-button type="link"
                @click="del(row.id)">删除</a-button>
    </div>
  </template>
</BaseTable>

<script>
import { reactive } from 'vue'

import Axios from 'axios'
const columns = [
  {
    title: '姓名',
    key: 'tags'
    dataIndex: 'peoName',
  },
  {
    title: '部门',
    dataIndex: 'department',
  },
  {
    title: '操作',
    key: 'action',
  },
]


const getCrossMonthApi =  (params) => {
    return Axios({
        url: '地址xxxx',
        method: 'GET',
        params
    })
};
// 请求参数,你需要什么就填什么
const employeeFilterFormData = reactive{  }


</script>

至此封装就完成啦,有什么问题可以私信或者留言噢,我会尽量解答。

猜你喜欢

转载自blog.csdn.net/autumnmn/article/details/130556774