当前位置:首页 > 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 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。组件的实现包括定义、注册、数据传递和生命周期管理等。 定义组件 组件可以通过单文件组件(.…

vue 菜单实现

vue 菜单实现

Vue 菜单实现方法 在Vue中实现菜单功能可以通过多种方式完成,以下是几种常见的实现方法: 使用v-for动态生成菜单 通过数据驱动的方式动态渲染菜单项,适合菜单内容可能变化的场景: <t…

vue实现例子

vue实现例子

以下是一些常见的 Vue 实现例子,涵盖基础功能到进阶应用场景: 基础数据绑定 使用 v-model 实现双向数据绑定: <template> <div> &l…

vue 实现穿透

vue 实现穿透

Vue 样式穿透的实现方法 在 Vue 中,样式穿透通常指在带有 scoped 属性的样式块中,强制影响子组件的样式。以下是几种常见的实现方式: 使用 >>> 或 /deep/ 选…

vue实现肢体识别

vue实现肢体识别

Vue 中实现肢体识别的方法 在 Vue 项目中实现肢体识别通常需要结合第三方库或 API,例如 TensorFlow.js、MediaPipe 或 OpenCV。以下是几种常见的实现方式: 使用…

简单实现vue github

简单实现vue github

实现一个简单的 Vue 项目并上传到 GitHub 创建 Vue 项目 使用 Vue CLI 快速初始化一个 Vue 项目,确保已安装 Node.js 和 npm/yarn。运行以下命令创建项目:…