当前位置:首页 > VUE

vue实现表格组件封装

2026-01-21 07:44:05VUE

封装 Vue 表格组件的核心思路

封装一个可复用的 Vue 表格组件需要考虑数据驱动、配置化、扩展性等核心要素。以下是实现方案的关键点:

基础表格结构设计

使用 Vue 的 v-for 指令动态渲染表头和表格数据
通过 props 接收外部传入的表格配置和数据

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

组件参数定义

props: {
  // 表格列配置
  columns: {
    type: Array,
    required: true,
    default: () => []
  },
  // 表格数据
  data: {
    type: Array,
    required: true,
    default: () => []
  },
  // 是否显示边框
  border: {
    type: Boolean,
    default: false
  }
}

支持自定义列模板

通过作用域插槽实现自定义列内容渲染

vue实现表格组件封装

<template v-for="col in columns" #[col.prop]="{ row }">
  <slot :name="col.prop" :row="row">
    {{ row[col.prop] }}
  </slot>
</template>

添加排序功能

methods: {
  handleSort(col) {
    if (!col.sortable) return
    this.data.sort((a, b) => {
      return col.sortMethod 
        ? col.sortMethod(a[col.prop], b[col.prop])
        : a[col.prop] - b[col.prop]
    })
  }
}

实现分页功能

computed: {
  paginatedData() {
    const start = (this.currentPage - 1) * this.pageSize
    return this.data.slice(start, start + this.pageSize)
  }
}

完整组件示例

<template>
  <div class="table-container">
    <table :class="['custom-table', { 'has-border': border }]">
      <!-- 表头 -->
      <thead>
        <tr>
          <th 
            v-for="col in columns" 
            :key="col.prop"
            @click="handleSort(col)"
          >
            {{ col.label }}
            <span v-if="col.sortable" class="sort-icon">
              {{ sortOrder === 'asc' ? '↑' : '↓' }}
            </span>
          </th>
        </tr>
      </thead>

      <!-- 表格内容 -->
      <tbody>
        <tr v-for="(row, index) in paginatedData" :key="index">
          <td v-for="col in columns" :key="col.prop">
            <slot :name="col.prop" :row="row">
              {{ row[col.prop] }}
            </slot>
          </td>
        </tr>
      </tbody>
    </table>

    <!-- 分页器 -->
    <div v-if="showPagination" class="pagination">
      <button @click="prevPage">上一页</button>
      <span>{{ currentPage }} / {{ totalPages }}</span>
      <button @click="nextPage">下一页</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SmartTable',
  props: {
    columns: Array,
    data: Array,
    border: Boolean,
    pageSize: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      currentPage: 1,
      sortOrder: 'asc'
    }
  },
  computed: {
    totalPages() {
      return Math.ceil(this.data.length / this.pageSize)
    },
    paginatedData() {
      const start = (this.currentPage - 1) * this.pageSize
      return this.data.slice(start, start + this.pageSize)
    },
    showPagination() {
      return this.data.length > this.pageSize
    }
  },
  methods: {
    handleSort(col) {
      if (!col.sortable) return
      this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
      this.data.sort((a, b) => {
        return col.sortMethod 
          ? col.sortMethod(a[col.prop], b[col.prop])
          : this.sortOrder === 'asc' 
            ? a[col.prop] - b[col.prop]
            : b[col.prop] - a[col.prop]
      })
    },
    prevPage() {
      if (this.currentPage > 1) this.currentPage--
    },
    nextPage() {
      if (this.currentPage < this.totalPages) this.currentPage++
    }
  }
}
</script>

组件使用示例

<template>
  <smart-table
    :columns="columns"
    :data="tableData"
    border
  >
    <template #status="{ row }">
      <span :class="['status', row.status]">
        {{ row.status }}
      </span>
    </template>
  </smart-table>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        { prop: 'name', label: '姓名' },
        { prop: 'age', label: '年龄', sortable: true },
        { prop: 'status', label: '状态' }
      ],
      tableData: [
        { name: '张三', age: 25, status: 'active' },
        { name: '李四', age: 30, status: 'inactive' }
      ]
    }
  }
}
</script>

高级功能扩展建议

  • 添加列宽拖动功能
  • 实现多列排序
  • 支持树形表格展示
  • 添加行选择功能
  • 实现单元格编辑功能
  • 支持虚拟滚动优化大数据量性能

通过合理的组件设计和配置化参数,可以构建出高度可复用的表格组件,满足各种业务场景需求。

标签: 组件表格
分享给朋友:

相关文章

怎么制作css表格

怎么制作css表格

使用HTML和CSS创建表格 HTML提供<table>标签用于创建表格结构,CSS用于控制样式。以下是一个基础示例: <table class="styled-table">…

uniapp组件写法

uniapp组件写法

Uniapp 组件的基本写法 Uniapp 的组件写法与 Vue 类似,支持单文件组件(.vue 文件)。一个基本的组件通常包含三个部分:<template>、<script>…

vue实现拖拽实现组件嵌套

vue实现拖拽实现组件嵌套

实现拖拽组件嵌套的核心思路 Vue中实现拖拽组件嵌套需要结合拖拽库(如vuedraggable)和组件递归渲染。核心在于动态管理嵌套数据结构,并通过事件传递实现层级更新。 安装必要依赖 推荐使用vu…

vue实现折叠组件

vue实现折叠组件

实现折叠组件的基本思路 在Vue中实现折叠组件通常需要利用动态绑定和条件渲染。核心是通过控制一个布尔值状态来决定内容是否显示,并添加过渡动画提升用户体验。 基础实现方法 使用v-show或v-if控…

css表格制作

css表格制作

CSS表格制作方法 使用CSS创建表格可以通过多种方式实现,以下是常见的几种方法: 使用HTML原生表格标签结合CSS样式 <table class="styled-table">…

组件elementui

组件elementui

ElementUI 简介 ElementUI 是一套基于 Vue.js 的桌面端组件库,由饿了么前端团队开发并开源。它提供了丰富的 UI 组件(如按钮、表单、表格等),适合快速构建企业级中后台产品。…