当前位置:首页 > VUE

vue实现表格组件封装

2026-01-21 07:44:05VUE

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

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

vue实现表格组件封装

基础表格结构设计

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

vue实现表格组件封装

<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
  }
}

支持自定义列模板

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

<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>

高级功能扩展建议

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

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

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

相关文章

如何实现vue表格联动

如何实现vue表格联动

实现 Vue 表格联动的方法 数据绑定与响应式更新 通过 Vue 的响应式特性,将多个表格的数据绑定到同一个数据源或计算属性。当一个表格的数据发生变化时,另一个表格会自动更新。例如: data()…

vue实现表格拖动列宽

vue实现表格拖动列宽

实现表格列宽拖动的核心思路 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽逻辑,动态修改列宽。需要处理表头与表体的联动,确保拖动时视觉一致。 基础HTML结构 &…

vue实现拖拽实现组件嵌套

vue实现拖拽实现组件嵌套

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

css表格制作

css表格制作

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

vue实现表格内容

vue实现表格内容

Vue实现表格内容的方法 使用原生HTML表格 在Vue模板中直接使用HTML的<table>标签构建表格结构,通过v-for指令动态渲染数据。 <template> &…

vue实现盖章组件

vue实现盖章组件

实现Vue盖章组件的步骤 组件结构设计 创建一个Vue组件,包含画布元素和必要的控制按钮。画布用于显示盖章效果,按钮用于触发盖章操作。组件需要接收图片和盖章位置等参数。 <template&g…