当前位置:首页 > VUE

vue实现table封装

2026-02-17 06:57:37VUE

封装 Vue Table 组件的基本思路

封装一个可复用的 Vue Table 组件需要考虑灵活性、可配置性和易用性。核心是通过 props 接收数据和配置,通过插槽(slots)提供自定义内容的能力。

基础 Table 封装示例

创建一个基础的表格组件,支持动态列和数据渲染:

<template>
  <table class="base-table">
    <thead>
      <tr>
        <th v-for="column in columns" :key="column.prop">
          {{ column.label }}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in data" :key="index">
        <td v-for="column in columns" :key="column.prop">
          {{ row[column.prop] }}
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  name: 'BaseTable',
  props: {
    columns: {
      type: Array,
      required: true,
      default: () => []
    },
    data: {
      type: Array,
      required: true,
      default: () => []
    }
  }
}
</script>

<style scoped>
.base-table {
  width: 100%;
  border-collapse: collapse;
}
.base-table th, .base-table td {
  border: 1px solid #ddd;
  padding: 8px;
}
.base-table th {
  background-color: #f2f2f2;
}
</style>

添加自定义列内容支持

通过作用域插槽允许自定义单元格内容:

vue实现table封装

<template>
  <table class="base-table">
    <thead>
      <tr>
        <th v-for="column in columns" :key="column.prop">
          {{ column.label }}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in data" :key="index">
        <td v-for="column in columns" :key="column.prop">
          <slot
            v-if="column.slot"
            :name="column.prop"
            :row="row"
            :index="index"
          ></slot>
          <template v-else>
            {{ row[column.prop] }}
          </template>
        </td>
      </tr>
    </tbody>
  </table>
</template>

添加排序功能

扩展组件支持列排序:

<script>
export default {
  name: 'SortableTable',
  props: {
    columns: {
      type: Array,
      required: true,
      default: () => []
    },
    data: {
      type: Array,
      required: true,
      default: () => []
    }
  },
  data() {
    return {
      sortKey: '',
      sortOrder: 'asc'
    }
  },
  computed: {
    sortedData() {
      if (!this.sortKey) return this.data

      return [...this.data].sort((a, b) => {
        const valA = a[this.sortKey]
        const valB = b[this.sortKey]

        if (this.sortOrder === 'asc') {
          return valA > valB ? 1 : -1
        } else {
          return valA < valB ? 1 : -1
        }
      })
    }
  },
  methods: {
    handleSort(prop) {
      if (this.sortKey === prop) {
        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
      } else {
        this.sortKey = prop
        this.sortOrder = 'asc'
      }
    }
  }
}
</script>

添加分页功能

扩展组件支持分页:

vue实现table封装

<template>
  <div>
    <table class="base-table">
      <!-- 表头 -->
      <thead>
        <tr>
          <th v-for="column in columns" :key="column.prop">
            {{ column.label }}
          </th>
        </tr>
      </thead>
      <!-- 表体 -->
      <tbody>
        <tr v-for="(row, index) in paginatedData" :key="index">
          <td v-for="column in columns" :key="column.prop">
            <slot
              v-if="column.slot"
              :name="column.prop"
              :row="row"
              :index="index"
            ></slot>
            <template v-else>
              {{ row[column.prop] }}
            </template>
          </td>
        </tr>
      </tbody>
    </table>

    <div class="pagination">
      <button @click="prevPage" :disabled="currentPage === 1">上一页</button>
      <span>第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
      <button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    columns: Array,
    data: Array,
    pageSize: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      currentPage: 1
    }
  },
  computed: {
    totalPages() {
      return Math.ceil(this.data.length / this.pageSize)
    },
    paginatedData() {
      const start = (this.currentPage - 1) * this.pageSize
      const end = start + this.pageSize
      return this.data.slice(start, end)
    }
  },
  methods: {
    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.currentPage++
      }
    },
    prevPage() {
      if (this.currentPage > 1) {
        this.currentPage--
      }
    }
  }
}
</script>

高级封装建议

对于更复杂的表格需求,可以考虑以下增强功能:

  • 添加行选择功能,支持单选和多选
  • 实现列固定和表头固定
  • 支持表格编辑功能
  • 添加树形表格展示
  • 实现虚拟滚动提升大数据量性能
  • 支持列拖拽排序
  • 添加表格导出功能

使用第三方库

对于复杂表格需求,可以考虑基于以下流行库进行二次封装:

  • Element UI 的 Table 组件
  • Ant Design Vue 的 Table 组件
  • VxeTable 专业表格解决方案
  • AG Grid 企业级表格组件

这些库已经提供了丰富的功能,可以通过二次封装来满足特定业务需求。

标签: vuetable
分享给朋友:

相关文章

vue实现屏幕共享

vue实现屏幕共享

Vue 实现屏幕共享的方法 使用 WebRTC 和 getDisplayMedia API 通过 navigator.mediaDevices.getDisplayMedia 捕获屏幕内容,结合 We…

vue实现一个标签选择

vue实现一个标签选择

Vue 标签选择组件实现 基础实现 使用 Vue 的 v-for 和 v-model 指令可以快速实现标签选择功能: <template> <div class="tag-se…

vue实现画图

vue实现画图

Vue 实现画图功能 在 Vue 中实现画图功能通常需要结合 HTML5 的 <canvas> 元素或第三方库。以下是几种常见的方法: 使用原生 Canvas API 通过 Vue 直接…

vue实现文字

vue实现文字

Vue 中实现文字显示的方法 在 Vue 中实现文字显示可以通过多种方式,包括插值表达式、指令、组件等。以下是几种常见的实现方法: 插值表达式 使用双大括号 {{ }} 进行文本插值,这是 Vue…

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template&g…

vue实现表白

vue实现表白

Vue 实现表白页面 使用 Vue 可以快速创建一个动态、交互式的表白页面。以下是一个简单的实现方案: 基础结构 创建一个 Vue 项目或单文件组件,包含以下核心部分: <templat…