vue3 TypeScript 与 Supabase 集成开发

一、类型系统的重要性

  1. 类型安全保障

    • 在编译时捕获错误,减少运行时异常
    • 确保数据结构一致性,从数据库到 UI 的全链路类型检查
    • 提供代码自动完成和智能提示,提高开发效率
  2. 类型定义分层

    • 数据库层(SQL):定义物理数据结构和关系
    • Supabase 类型层(supabase.ts):自动生成的数据库类型映射
    • 业务类型层(types/):扩展数据库类型,添加业务逻辑
    • API 接口层:定义请求和响应类型
    • UI 组件层:定义表单和视图相关类型

二、核心文件和目录作用

  1. 数据库定义(用户管理.sql)

    • 表结构定义(departments, roles, profiles 等)
    • 视图创建(view_user_details, view_user_roles)
    • 触发器和函数(update_modified_column, handle_new_user)
    • 行级安全策略(RLS)设置
  2. Supabase 类型(supabase.ts)

    • 自动生成的数据库结构完整映射
    • 提供 Tables, TablesInsert, TablesUpdate 等辅助类型
    • 定义表与表之间的关系(Relationships)
    • 通过 npx supabase gen types 命令更新
  3. 业务类型目录(types/)

    • index.ts:集中导出所有类型
    • system/:系统模块类型(profile, department, role 等)
    • common/:通用类型(API 响应、分页、错误类型等)
    • 业务模块/:其他业务模块的类型定义
  4. API 服务层(api/)

    • 封装与 Supabase 的通信
    • 实现 CRUD 操作和复杂查询
    • 处理错误和响应格式化
    • 使用 types/ 定义的类型作为参数和返回值
  5. 状态管理(stores/)

    • 使用 Pinia 管理全局状态
    • 调用 API 方法获取和修改数据
    • 维护 UI 状态(加载、错误等)
    • 提供计算属性和操作方法
  6. 视图层(views/)

    • 使用组件渲染 UI
    • 通过 stores/ 获取和操作数据
    • 处理用户交互和表单提交
    • 使用类型保证模板和数据一致性

三、完整数据流程

1. 开发流程

  1. 数据库设计与更新

    • 编写 SQL 创建或修改表结构
    • 在 Supabase 中执行 SQL 或使用迁移工具
  2. 类型生成与扩展

    • 运行 npx supabase gen types 更新 supabase.ts
    • 更新业务类型定义,扩展数据库类型
  3. API 服务实现

    • 基于最新类型定义,实现或更新 API 方法
    • 使用 Supabase 客户端执行查询和操作
  4. 状态管理更新

    • 更新 Pinia store,使用新的类型和 API 方法
    • 实现业务逻辑和状态管理
  5. UI 组件开发

    • 基于类型和状态创建或更新组件
    • 实现用户交互和数据展示

2. 数据操作流程

创建数据流程

  1. 用户在表单中输入数据
  2. 提交表单触发组件中的方法
  3. 组件调用 store 中的 action
  4. Store action 调用 API 服务方法
  5. API 服务使用 Supabase 客户端发送请求
  6. Supabase 执行数据库操作
  7. 响应沿原路径返回
  8. UI 更新展示结果

查询数据流程

  1. 组件挂载或交互触发查询
  2. 组件调用 store 中的 action
  3. Store action 调用 API 服务方法
  4. API 服务构建查询并执行
  5. Supabase 返回查询结果
  6. API 服务格式化响应
  7. Store 更新状态
  8. 组件重新渲染展示数据

四、数据流程图

┌────────────────┐       ┌─────────────────┐       ┌──────────────────┐
│                │       │                 │       │                  │
│  用户管理.sql  │       │   supabase.ts   │       │  types/*.ts     │
│  (数据库定义)  │─────▶│(自动生成类型映射)│─────▶│ (业务类型扩展)   │
│                │       │                 │       │                  │
└────────────────┘       └─────────────────┘       └──────────┬───────┘
                                                             │
                                                             ▼
┌────────────────┐       ┌─────────────────┐       ┌──────────────────┐
│                │       │                 │       │                  │
│   views/*.vue  │◀─────│  stores/*.ts    │◀─────│    api/*.ts      │
│   (视图组件)   │       │  (状态管理)     │       │  (API服务)      │
│                │       │                 │       │                  │
└───────┬────────┘       └────────┬────────┘       └──────────┬───────┘
        │                         │                           │
        └─────────────────────────▼───────────────────────────┘
                                  │
                                  ▼
                        ┌─────────────────┐
                        │                 │
                        │  Supabase API   │
                        │                 │
                        └────────┬────────┘
                                 │
                                 ▼
                        ┌─────────────────┐
                        │                 │
                        │     数据库      │
                        │                 │
                        └─────────────────┘

五、实际数据流示例

查询用户列表

1. views/system/ProfileList.vue:
   - onMounted(() => profileStore.fetchProfiles(query))

2. stores/system/profile.ts:
   - async fetchProfiles(query) { profiles.value = await getProfiles(query) }

3. api/system/profileService.ts:
   - async getProfiles(query: ProfileQuery): Promise<Profile[]> {
       const { data } = await supabase.from('profiles').select('*')
       return data
     }

4. Supabase 执行 SQL 查询:
   - SELECT * FROM profiles WHERE ...

5. 数据返回至 Store:
   - profiles.value = 查询结果

6. 组件重新渲染:
   - <template><div v-for="profile in profileStore.profiles">...</div></template>

创建新用户

1. views/system/ProfileForm.vue:
   - async handleSubmit() { await profileStore.saveProfile(formData) }

2. stores/system/profile.ts:
   - async saveProfile(data) { return await createProfile(data) }

3. api/system/profileService.ts:
   - async createProfile(data: CreateProfileRequest): Promise<Profile> {
       const { data: profile } = await supabase.from('profiles').insert(data).select()
       return profile
     }

4. Supabase 执行 SQL 插入:
   - INSERT INTO profiles (...) VALUES (...)

5. 数据返回至组件:
   - router.push('/profiles') 跳转到列表页

六、核心优势总结

  1. 类型安全保障

    • 编译时捕获错误,减少运行时异常
    • IDE 提供智能提示和自动完成
    • 类型即文档,减少注释需求
  2. 代码组织清晰

    • 关注点分离,职责明确
    • 逻辑复用,避免重复代码
    • 模块化结构便于团队协作
  3. 业务逻辑扩展

    • 基于数据库类型扩展业务类型
    • 添加非数据库字段和计算属性
    • 处理复杂数据结构如树形组织
  4. 全链路类型保障

    • 从数据库到 UI 的一致性保证
    • API 请求和响应类型明确
    • 状态和组件的类型匹配
  5. 适应变更的能力

    • 数据库变更时简单更新类型
    • 类型错误提前暴露潜在问题
    • 重构时可靠的类型检查支持

这种全链路类型驱动的开发模式是 Vue 3 + TypeScript + Supabase 项目的最佳实践,让应用更加健壮、可维护且易于扩展。

项目结构

---
description: 
globs: 
alwaysApply: true
---
project-root/
├── public/                      # 静态资源
│   ├── favicon.ico              # 网站图标
│   └── logo.png                 # 公司logo
├── src/                         # 源代码
│   ├── assets/                  # 资源文件
│   │   ├── images/              # 图片资源
│   │   └── styles/              # 样式文件
│   │       ├── variables.scss   # SCSS变量
│   │       └── global.scss      # 全局样式
│   ├── layouts/                 # 布局组件
│   │   ├── MainLayout.vue       # 主布局容器
│   │   └── BlankLayout.vue      # 空白布局(登录页用)
│   ├── views/                   # 页面视图(每个功能一个页面)
│   │   ├── Dashboard.vue        # 首页/仪表盘
│   │   ├── indicators/          # 指标管理模块
│   │   │   └── IndicatorManage.vue  # 指标管理(包含增删改查)
│   │   ├── accidents/           # 事故管理模块
│   │   │   └── AccidentManage.vue   # 事故管理(包含增删改查)
│   │   ├── reports/             # 报表模块
│   │   │   └── ReportManage.vue     # 报表管理(包含创建、查看)
│   │   └── system/              # 系统管理模块
│   │       ├── UserManage.vue       # 用户管理
│   │       ├── RoleManage.vue       # 角色管理
│   │       └── SystemSetting.vue    # 系统设置
│   ├── services/                # 服务层(统一处理数据交互)
│   │   ├── supabase/            # Supabase服务
│   │   │   ├── client.ts        # Supabase客户端配置
│   │   │   ├── auth.ts          # 认证服务
│   │   │   └── storage.ts       # 文件存储服务
│   │   ├── indicators/          # 指标服务
│   │   │   └── index.ts         # 指标数据操作
│   │   ├── accidents/           # 事故服务
│   │   │   └── index.ts         # 事故数据操作
│   │   ├── reports/             # 报表服务
│   │   │   └── index.ts         # 报表数据操作
│   │   ├── system/              # 系统服务
│   │   │   ├── users.ts         # 用户数据操作
│   │   │   └── roles.ts         # 角色数据操作
│   │   └── hr/                  # HR系统集成
│   │       └── index.ts         # HR数据集成服务
│   ├── stores/                  # Pinia状态管理
│   │   ├── index.ts             # 状态管理入口
│   │   ├── indicators/          # 指标状态
│   │   │   └── index.ts         # 指标状态管理
│   │   ├── accidents/           # 事故状态
│   │   │   └── index.ts         # 事故状态管理
│   │   ├── reports/             # 报表状态
│   │   │   └── index.ts         # 报表状态管理
│   │   └── system/              # 系统状态
│   │       ├── auth.ts          # 认证状态
│   │       ├── users.ts         # 用户状态
│   │       └── roles.ts         # 角色状态
│   ├── utils/                   # 工具函数
│   │   ├── formatters.ts        # 格式化工具
│   │   └── calculations.ts      # CCPS计算工具
│   ├── types/                   # TypeScript类型
│   │   ├── index.ts             # 类型导出入口
│   │   ├── database.ts          # 数据库表类型(Supabase生成)
│   │   ├── enums.ts             # 枚举类型定义
│   │   └── interfaces/          # 接口类型定义
│   │       ├── common.ts        # 通用接口
│   │       ├── indicator.ts     # 指标接口
│   │       ├── accident.ts      # 事故接口
│   │       ├── report.ts        # 报表接口
│   │       └── user.ts          # 用户接口
│   ├── router/                  # 路由配置
│   │   ├── index.ts             # 路由入口
│   │   └── routes.ts            # 路由定义
│   ├── App.vue                  # 根组件
│   └── main.ts                  # 入口文件
├── doc/                         # 文档
│   ├── 技术方案.md               # 技术方案文档
│   └── 项目构建历史.md           # 项目构建历史
├── vite.config.ts               # Vite配置
├── package.json                 # 项目依赖
└── README.md                    # 项目说明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z日火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值