《Vue3 组合式 API 实战:封装可复用的表格组件(附源码)》

在现代前端开发中,Vue3 的组合式 API 提供了一种更灵活、更模块化的方式来构建组件。封装可复用的表格组件是常见需求,它可以提升开发效率,减少重复代码。本文将一步步指导你如何使用组合式 API 创建一个基本表格组件,支持数据渲染、排序和分页功能。所有代码均使用 Vue3 的 Composition API 实现,并确保组件高度可复用。

步骤 1: 组件设计思路
  • 目标:创建一个可复用的表格组件,接收外部数据源,支持自定义列、排序和分页。
  • 核心概念:使用 setup() 函数定义响应式状态和逻辑,通过 props 接收数据,利用 computedref 管理状态。
  • 优势:组合式 API 允许逻辑复用,例如将排序逻辑封装为独立函数,便于在其他组件中共享。
步骤 2: 实现基本表格结构

首先,定义组件的 HTML 模板和基本 props。组件接收 data(数据数组)和 columns(列定义数组)作为输入。

<template>
  <table>
    <thead>
      <tr>
        <th v-for="column in columns" :key="column.key" @click="sortBy(column.key)">
          {{ column.title }}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in paginatedData" :key="item.id">
        <td v-for="column in columns" :key="column.key">
          {{ item[column.key] }}
        </td>
      </tr>
    </tbody>
  </table>
  <div>
    <button @click="prevPage">上一页</button>
    <span>第 {{ currentPage }} 页</span>
    <button @click="nextPage">下一页</button>
  </div>
</template>

<script>
import { ref, computed } from 'vue';

export default {
  props: {
    data: {
      type: Array,
      required: true
    },
    columns: {
      type: Array,
      required: true
    },
    pageSize: {
      type: Number,
      default: 5
    }
  },
  setup(props) {
    // 响应式状态定义
    const currentPage = ref(1);
    const sortKey = ref('');
    const sortDirection = ref('asc');

    // 计算属性:处理排序后的数据
    const sortedData = computed(() => {
      if (!sortKey.value) return props.data;
      return [...props.data].sort((a, b) => {
        const aValue = a[sortKey.value];
        const bValue = b[sortKey.value];
        if (aValue < bValue) return sortDirection.value === 'asc' ? -1 : 1;
        if (aValue > bValue) return sortDirection.value === 'asc' ? 1 : -1;
        return 0;
      });
    });

    // 计算属性:分页数据
    const paginatedData = computed(() => {
      const start = (currentPage.value - 1) * props.pageSize;
      const end = start + props.pageSize;
      return sortedData.value.slice(start, end);
    });

    // 方法:排序逻辑
    const sortBy = (key) => {
      if (sortKey.value === key) {
        sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc';
      } else {
        sortKey.value = key;
        sortDirection.value = 'asc';
      }
    };

    // 方法:分页控制
    const prevPage = () => {
      if (currentPage.value > 1) currentPage.value--;
    };
    const nextPage = () => {
      const totalPages = Math.ceil(sortedData.value.length / props.pageSize);
      if (currentPage.value < totalPages) currentPage.value++;
    };

    return {
      currentPage,
      paginatedData,
      sortBy,
      prevPage,
      nextPage
    };
  }
};
</script>

步骤 3: 使用组件示例

在父组件中导入并使用这个表格组件,传递自定义数据和列定义。这展示了组件的可复用性:只需更改 datacolumns,即可适应不同场景。

<template>
  <div>
    <h2>用户列表</h2>
    <ReusableTable :data="users" :columns="userColumns" :pageSize="3" />
  </div>
</template>

<script>
import ReusableTable from './ReusableTable.vue';
import { ref } from 'vue';

export default {
  components: {
    ReusableTable
  },
  setup() {
    const users = ref([
      { id: 1, name: '张三', age: 25 },
      { id: 2, name: '李四', age: 30 },
      { id: 3, name: '王五', age: 28 },
      { id: 4, name: '赵六', age: 22 }
    ]);

    const userColumns = ref([
      { key: 'name', title: '姓名' },
      { key: 'age', title: '年龄' }
    ]);

    return {
      users,
      userColumns
    };
  }
};
</script>

源码说明
  • 完整代码:以上代码块可直接复制到 Vue3 项目中运行。组件使用纯 Composition API,无依赖外部库。
  • 功能亮点
    • 排序:点击表头切换排序方向(升序/降序)。
    • 分页:内置分页逻辑,通过 pageSize 控制每页条目数。
    • 响应式:所有状态使用 refcomputed 确保 UI 自动更新。
  • 扩展建议:为增强可复用性,可添加 slots 支持自定义单元格渲染,或通过事件发射(emit)处理行点击。
总结

通过组合式 API 封装表格组件,我们实现了逻辑与 UI 的解耦,使代码更易维护和测试。本示例展示了 Vue3 的核心优势:模块化、响应式和高效复用。你可以基于此源码扩展更多功能,如过滤、搜索或集成 TypeScript。尝试在自己的项目中应用,体验组合式 API 的强大!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐