最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue+Ant Design開發(fā)簡單表格組件的實戰(zhàn)指南

 更新時間:2025年06月25日 10:34:58   作者:碼農(nóng)阿豪@新空間  
在現(xiàn)代前端開發(fā)中,數(shù)據(jù)表格是展示信息最常用的組件之一,本文主要為大家介紹了一個基于Vue和Ant Design的表格組件開發(fā)過程,感興趣的可以了解下

前言

在現(xiàn)代前端開發(fā)中,數(shù)據(jù)表格是展示信息最常用的組件之一。本文將詳細記錄一個基于Vue和Ant Design的表格組件開發(fā)過程,從最初的需求實現(xiàn)到遇到問題,再到最終優(yōu)化方案的完整思考過程。通過這個實際案例,我們將探討如何構(gòu)建一個高效、用戶友好的數(shù)據(jù)表格組件,特別是處理固定列和滾動區(qū)域的復(fù)雜交互。

一、項目背景與需求分析

我們的項目需要開發(fā)一個媒體廣告抓取記錄查看功能,主要需求包括:

  • 展示媒體廣告位的抓取記錄數(shù)據(jù)
  • 支持分頁和排序功能
  • 關(guān)鍵信息需要固定顯示(左右兩側(cè))
  • 中間區(qū)域可橫向滾動查看更多數(shù)據(jù)字段
  • 良好的性能表現(xiàn),支持大數(shù)據(jù)量

基于這些需求,我們選擇了Ant Design Vue作為UI組件庫,其強大的Table組件非常適合這類需求。

二、基礎(chǔ)實現(xiàn)

2.1 組件結(jié)構(gòu)設(shè)計

首先我們創(chuàng)建了GraspingRecordModal.vue組件,基礎(chǔ)結(jié)構(gòu)如下:

<template>
  <a-modal
    title="抓取記錄"
    :visible="visible"
    width="90%"
    :footer="null"
    @cancel="handleCancel"
  >
    <a-table
      rowKey="id"
      :columns="columns"
      :dataSource="data"
      :pagination="pagination"
      :loading="loading"
      @change="handleTableChange"
    >
      <!-- 自定義渲染插槽 -->
    </a-table>
  </a-modal>
</template>

2.2 數(shù)據(jù)獲取與處理

數(shù)據(jù)獲取使用異步請求,處理函數(shù)如下:

async fetchData() {
  this.loading = true;
  try {
    const { data: res } = await getGraspingRecords({
      mediaAdId: this.mediaAdId,
      page: this.pagination.current,
      pageSize: this.pagination.pageSize
    });
    
    if (res.code === '000000') {
      this.data = res.data.aaData || [];
      this.pagination.total = res.data.iTotalRecords || 0;
    } else {
      throw new Error(res.msg || '獲取數(shù)據(jù)失敗');
    }
  } catch (error) {
    console.error('獲取抓取記錄失敗:', error);
    this.$message.error(error.message);
  } finally {
    this.loading = false;
  }
}

2.3 初始列配置

最初的列配置嘗試固定左右兩側(cè)的關(guān)鍵信息:

columns: [
  {
    title: '任務(wù)ID',
    dataIndex: 'graspingTaskId',
    width: 180,
    fixed: 'left'
  },
  // ...其他中間列...
  {
    title: '狀態(tài)',
    dataIndex: 'graspingStatus',
    scopedSlots: { customRender: 'graspingStatus' },
    width: 100,
    fixed: 'right'
  }
]

三、遇到的問題與初步解決方案

3.1 空白表格區(qū)域問題

在初步實現(xiàn)中,我們發(fā)現(xiàn)表格左右兩側(cè)出現(xiàn)了不必要的空白區(qū)域,這嚴重影響了用戶體驗和視覺效果。

問題表現(xiàn):

  • 固定列與非固定列之間存在間隙
  • 滾動區(qū)域兩側(cè)出現(xiàn)空白
  • 表格整體布局不緊湊

3.2 原因分析

經(jīng)過調(diào)試,我們發(fā)現(xiàn)了幾個關(guān)鍵問題:

  • 寬度計算不準確:固定列和非固定列的寬度總和與表格容器寬度不匹配
  • 滾動設(shè)置不當(dāng):scroll.x值設(shè)置不合理
  • CSS樣式?jīng)_突:Ant Design默認樣式與我們的需求有沖突

3.3 初步修復(fù)嘗試

我們首先嘗試調(diào)整列寬和滾動設(shè)置:

:scroll="{ x: 1800 }"  // 根據(jù)列寬總和設(shè)置固定值

同時調(diào)整了一些列的寬度:

{
  title: '任務(wù)ID',
  dataIndex: 'graspingTaskId',
  width: 150,  // 縮小寬度
  fixed: 'left',
  ellipsis: true  // 添加省略號
}

四、深度優(yōu)化方案

4.1 完美的解決方案

經(jīng)過多次嘗試,我們找到了最合適的配置方案:

<a-table
  :scroll="{ x: 'max-content' }"
  :columns="columns"
  bordered
  size="middle"
>

配合以下CSS修正:

.grasping-record-modal >>> .ant-table {
  min-width: 100%;
}
.grasping-record-modal >>> .ant-table-container {
  overflow-x: auto !important;
}
.grasping-record-modal >>> .ant-table-body {
  overflow-x: auto !important;
}

4.2 優(yōu)化后的列配置

columns: [
  {
    title: '任務(wù)ID',
    dataIndex: 'graspingTaskId',
    width: 180,
    fixed: 'left',
    ellipsis: true
  },
  {
    title: '總?cè)罩緮?shù)',
    dataIndex: 'totalCount',
    width: 100,
    fixed: 'left',
    align: 'center'
  },
  // 中間可滾動列...
  {
    title: '狀態(tài)',
    dataIndex: 'graspingStatus',
    scopedSlots: { customRender: 'graspingStatus' },
    width: 100,
    fixed: 'right',
    align: 'center'
  },
  {
    title: '抓取時間',
    dataIndex: 'graspingTime',
    scopedSlots: { customRender: 'time' },
    width: 180,
    fixed: 'right'
  }
]

4.3 關(guān)鍵優(yōu)化點

  • 使用’max-content’:讓表格根據(jù)內(nèi)容自動計算寬度
  • 強制溢出設(shè)置:確保滾動行為符合預(yù)期
  • 最小寬度保證:防止容器意外收縮
  • 列對齊統(tǒng)一:所有數(shù)值列居中對齊
  • 固定列優(yōu)化:左右兩側(cè)固定列寬度適當(dāng)加大

五、完整優(yōu)化代碼

以下是經(jīng)過全面優(yōu)化后的完整組件代碼:

<template>
  <a-modal
    title="抓取記錄"
    :visible="visible"
    width="90%"
    :footer="null"
    @cancel="handleCancel"
    :destroyOnClose="true"
    class="grasping-record-modal"
  >
    <a-table
      rowKey="id"
      :columns="columns"
      :dataSource="data"
      :pagination="pagination"
      :loading="loading"
      :scroll="{ x: 'max-content' }"
      @change="handleTableChange"
      bordered
      size="middle"
    >
      <template slot="graspingStatus" slot-scope="text">
        <a-tag :color="getStatusColor(text)">
          {{ getStatusText(text) }}
        </a-tag>
      </template>
      <template slot="time" slot-scope="text">
        {{ formatDateTime(text) }}
      </template>
    </a-table>
  </a-modal>
</template>

<script>
import dayjs from 'dayjs'
import { getGraspingRecords } from '@/api/ad-api/media'

export default {
  name: 'GraspingRecordModal',
  data() {
    return {
      loading: false,
      data: [],
      pagination: {
        current: 1,
        pageSize: 10,
        total: 0,
        showSizeChanger: true,
        pageSizeOptions: ['10', '20', '50', '100'],
        showTotal: total => `共 ${total} 條記錄`
      },
      columns: [
        {
          title: '任務(wù)ID',
          dataIndex: 'graspingTaskId',
          width: 180,
          fixed: 'left',
          ellipsis: true
        },
        {
          title: '總?cè)罩緮?shù)',
          dataIndex: 'totalCount',
          width: 100,
          fixed: 'left',
          align: 'center'
        },
        {
          title: '設(shè)備ID',
          dataIndex: 'deviceIdCount',
          width: 100,
          align: 'center'
        },
        {
          title: '啟動時間',
          dataIndex: 'bootTimeSecCount',
          width: 100,
          align: 'center'
        },
        {
          title: '系統(tǒng)更新時間',
          dataIndex: 'osUpdateTimeSecCount',
          width: 120,
          align: 'center'
        },
        {
          title: '初始化時間',
          dataIndex: 'birthTimeCount',
          width: 100,
          align: 'center'
        },
        {
          title: 'caids',
          dataIndex: 'caidsCount',
          width: 100,
          align: 'center'
        },
        {
          title: '系統(tǒng)編譯時間',
          dataIndex: 'sysComplingTimeCount',
          width: 120,
          align: 'center'
        },
        {
          title: 'IDFA',
          dataIndex: 'idfaCount',
          width: 100,
          align: 'center'
        },
        {
          title: 'IMSI',
          dataIndex: 'imsiCount',
          width: 100,
          align: 'center'
        },
        {
          title: '安裝包列表',
          dataIndex: 'appListCount',
          width: 120,
          align: 'center'
        },
        {
          title: '狀態(tài)',
          dataIndex: 'graspingStatus',
          scopedSlots: { customRender: 'graspingStatus' },
          width: 100,
          fixed: 'right',
          align: 'center'
        },
        {
          title: '抓取時間',
          dataIndex: 'graspingTime',
          scopedSlots: { customRender: 'time' },
          width: 180,
          fixed: 'right'
        }
      ]
    }
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    mediaAdId: {
      type: [Number, String],
      required: true
    }
  },
  methods: {
    formatDateTime(timeStr) {
      return timeStr ? dayjs(timeStr).format('YYYY-MM-DD HH:mm:ss') : '-'
    },
    getStatusText(status) {
      const map = { 0: '失敗', 1: '成功', 2: '部分成功' }
      return map[status] || '未知'
    },
    getStatusColor(status) {
      const map = { 0: 'red', 1: 'green', 2: 'orange' }
      return map[status] || 'default'
    },
    handleTableChange(pagination) {
      this.pagination.current = pagination.current
      this.pagination.pageSize = pagination.pageSize
      this.fetchData()
    },
    async fetchData() {
      this.loading = true
      try {
        const { data: res } = await getGraspingRecords({
          mediaAdId: this.mediaAdId,
          page: this.pagination.current,
          pageSize: this.pagination.pageSize
        })
        if (res.code === '000000') {
          this.data = res.data.aaData || []
          this.pagination.total = res.data.iTotalRecords || 0
        } else {
          throw new Error(res.msg || '獲取數(shù)據(jù)失敗')
        }
      } catch (error) {
        console.error('獲取抓取記錄失敗:', error)
        this.$message.error(error.message)
      } finally {
        this.loading = false
      }
    },
    handleCancel() {
      this.$emit('close')
    }
  }
}
</script>

<style scoped>
.grasping-record-modal >>> .ant-table {
  min-width: 100%;
}
.grasping-record-modal >>> .ant-table-container {
  overflow-x: auto !important;
}
.grasping-record-modal >>> .ant-table-body {
  overflow-x: auto !important;
}
</style>

六、總結(jié)與最佳實踐

通過這個案例,我們總結(jié)出以下Ant Design Table組件的最佳實踐:

1.固定列設(shè)計:

  • 關(guān)鍵信息固定在左右兩側(cè)
  • 固定列寬度適當(dāng)加大
  • 添加ellipsis防止長文本溢出

2.滾動區(qū)域優(yōu)化:

  • 使用scroll="{ x: 'max-content' }"
  • 配合CSS強制溢出設(shè)置
  • 確保表格寬度自適應(yīng)

3.性能考慮:

  • 合理設(shè)置分頁大小
  • 使用loading狀態(tài)提升用戶體驗
  • 大數(shù)據(jù)量時考慮虛擬滾動

4.視覺一致性:

  • 數(shù)值列居中對齊
  • 狀態(tài)使用標簽顏色區(qū)分
  • 時間統(tǒng)一格式化

5.健壯性保障:

  • 數(shù)據(jù)獲取錯誤處理
  • 空狀態(tài)處理
  • 分頁參數(shù)校驗

這個案例展示了如何通過迭代優(yōu)化解決實際問題,最終實現(xiàn)了一個既美觀又實用的數(shù)據(jù)表格組件。希望這些經(jīng)驗?zāi)軒椭阍谖磥淼捻椖恐懈玫厥褂肁nt Design Table組件。

到此這篇關(guān)于Vue+Ant Design開發(fā)簡單表格組件的實戰(zhàn)指南的文章就介紹到這了,更多相關(guān)Vue Ant Design組件開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談 Vue 項目優(yōu)化的方法

    淺談 Vue 項目優(yōu)化的方法

    這篇文章主要介紹了淺談 Vue 項目優(yōu)化的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • 關(guān)于vue.extend的使用及說明

    關(guān)于vue.extend的使用及說明

    這篇文章主要介紹了關(guān)于vue.extend的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • vue.js+element 默認提示中英文操作

    vue.js+element 默認提示中英文操作

    這篇文章主要介紹了vue.js+element 默認提示中英文實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • vue前端el-input輸入限制輸入位數(shù)及輸入規(guī)則

    vue前端el-input輸入限制輸入位數(shù)及輸入規(guī)則

    這篇文章主要給大家介紹了關(guān)于vue前端el-input輸入限制輸入位數(shù)及輸入規(guī)則的相關(guān)資料,文中通過代碼介紹的介紹的非常詳細,對大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Vue3實現(xiàn)全局自動大寫轉(zhuǎn)換的兩種方案

    Vue3實現(xiàn)全局自動大寫轉(zhuǎn)換的兩種方案

    本文介紹了在Vue項目中使輸入框內(nèi)容自動轉(zhuǎn)為大寫的兩種方案:一種是自定義指令v-input-uppercase,適用于對特定輸入框進行精細化控制;另一種是全局插件,適用于全站所有輸入框,推薦使用,兩種方案均能處理中文輸入法兼容問題,合并成一個插件可同時實現(xiàn)兩個功能
    2026-04-04
  • element日歷calendar組件上月、今天、下月、日歷塊點擊事件及模板源碼

    element日歷calendar組件上月、今天、下月、日歷塊點擊事件及模板源碼

    這篇文章主要介紹了element日歷calendar組件上月、今天、下月、日歷塊點擊事件及模板源碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 從零開始用webpack構(gòu)建一個vue3.0項目工程的實現(xiàn)

    從零開始用webpack構(gòu)建一個vue3.0項目工程的實現(xiàn)

    這篇文章主要介紹了從零開始用webpack構(gòu)建一個vue3.0項目工程的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • vue實現(xiàn)登錄注冊模板的示例代碼

    vue實現(xiàn)登錄注冊模板的示例代碼

    這篇文章主要介紹了vue實現(xiàn)登錄注冊模板的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 基于element-ui對話框el-dialog初始化的校驗問題解決

    基于element-ui對話框el-dialog初始化的校驗問題解決

    這篇文章主要介紹了基于element-ui對話框el-dialog初始化的校驗問題解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • swiper在vue項目中l(wèi)oop循環(huán)輪播失效的解決方法

    swiper在vue項目中l(wèi)oop循環(huán)輪播失效的解決方法

    今天小編就為大家分享一篇swiper在vue項目中l(wèi)oop循環(huán)輪播失效的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09

最新評論

新丰县| 崇左市| 砀山县| 甘孜县| 河间市| 登封市| 额济纳旗| 沧源| 锦屏县| 钟祥市| 乐清市| 辽宁省| 蒙城县| 尤溪县| 建宁县| 陵川县| 榆林市| 麦盖提县| 乐亭县| 黄平县| 钦州市| 连云港市| 塔城市| 平江县| 虎林市| 泽普县| 汝城县| 邳州市| 葵青区| 盐亭县| 祁门县| 澄迈县| 富蕴县| 济南市| 三江| 连南| 林甸县| 金坛市| 民勤县| 延津县| 蕉岭县|