当前位置:首页 > 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 指令实现 Vue 指令是 Vue.js 提供的特殊属性,用于在 DOM 元素上添加特殊行为。指令以 v- 前缀开头,例如 v-model、v-if、v-for 等。以下是实现自定义指令和常用内…

vue实现通知

vue实现通知

Vue 实现通知功能的方法 使用 Vue 实现通知功能可以通过多种方式实现,以下是一些常见的方法: 使用 Vue 的全局事件总线 在 Vue 中可以通过事件总线实现通知功能。创建一个全局事件总线,然…

vue实现erp

vue实现erp

Vue实现ERP系统的关键步骤 技术选型与架构设计 采用Vue 3 + TypeScript构建前端,搭配Pinia状态管理,Element Plus或Ant Design Vue作为UI框架。后端可…

vue实现计算

vue实现计算

Vue 实现计算的方法 在 Vue 中实现计算功能可以通过多种方式完成,主要包括计算属性(computed)、方法(methods)和侦听器(watch)。以下是具体的实现方法: 计算属性(Comp…

vue实现ios

vue实现ios

Vue 实现 iOS 风格应用 使用 Vue 实现 iOS 风格的应用,可以通过结合 UI 框架和自定义样式来达成目标。以下是具体方法和步骤: 选择 iOS 风格的 UI 框架 Vue 生态中有多…

vue实现标题

vue实现标题

Vue 实现标题的方法 在Vue中实现标题可以通过多种方式,以下是几种常见的方法: 方法一:使用模板语法 在Vue组件的模板中直接使用HTML的<h1>到<h6>标签来定义…