当前位置:首页 > 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实现拍照

Vue实现拍照功能 在Vue中实现拍照功能通常需要结合浏览器的MediaDevices API和Canvas元素。以下是具体实现方法: 安装依赖(可选) 如果需要更简单的封装,可以安装vue-web…

vue实现选择置顶

vue实现选择置顶

Vue 实现选择置顶功能 在 Vue 中实现选择置顶功能,可以通过操作数据数组或结合 CSS 样式来实现。以下是几种常见的实现方法: 数组排序法 通过操作数据数组,将被选中的项移动到数组首位: /…

vue实现饼图

vue实现饼图

使用 ECharts 实现 Vue 饼图 安装 ECharts 依赖 npm install echarts --save 在 Vue 组件中引入 ECharts import * as echa…

vue 实现页面注册

vue 实现页面注册

Vue 实现页面注册功能 创建注册表单组件 在 Vue 项目中创建一个注册表单组件,通常命名为 Register.vue。该组件包含用户名、邮箱、密码等输入字段,以及提交按钮。 <templa…

vue实现全屏滚动

vue实现全屏滚动

实现全屏滚动的 Vue 方法 使用第三方库 vue-fullpage.js 安装 vue-fullpage.js: npm install vue-fullpage.js 在 Vue 项目中引入并注…