简介:本文详细讲解如何在 Nuxt3 项目中集成 Supabase 数据库,涵盖环境准备、API 密钥配置、安全连接、CRUD 操作及错误处理等关键步骤,助力开发者快速构建全栈应用。
在 Nuxt3 开发中,数据库的配置与集成是构建全栈应用的核心环节。Supabase 作为开源的 Firebase 替代方案,提供 PostgreSQL 数据库、实时订阅、身份验证等功能,其 Serverless 特性与 Nuxt3 的 SSR/SSG 模式高度契合。本文将系统讲解如何在 Nuxt3 项目中配置 Supabase 数据库,涵盖环境准备、API 密钥管理、安全连接、CRUD 操作及错误处理等关键环节。
访问 Supabase 官网 完成注册,进入控制台后点击 “New Project” 创建项目。需填写项目名称、选择数据库区域(建议选择离用户最近的区域以降低延迟),并设置密码。项目创建后,Supabase 会自动生成 PostgreSQL 数据库及配套的 REST/GraphQL API。
在项目仪表盘的 “Settings” > “API” 选项卡中,可找到以下关键信息:
https://xyz.supabase.co)⚠️ 安全提示:切勿将
SUPABASE_SERVICE_ROLE_KEY暴露在前端代码中,建议通过环境变量或后端 API 传递。
在 Nuxt3 项目中安装官方客户端库:
npm install @supabase/supabase-js# 或yarn add @supabase/supabase-js
在 server/api 或 utils 目录下创建 supabase.ts 文件,封装客户端初始化逻辑:
import { createClient } from '@supabase/supabase-js'const supabaseUrl = process.env.SUPABASE_URL || ''const supabaseAnonKey = process.env.SUPABASE_ANON_KEY || ''export const supabase = createClient(supabaseUrl, supabaseAnonKey)// 服务端专用客户端(需传递 serviceRoleKey)export const createServiceSupabase = (serviceRoleKey: string) => {return createClient(supabaseUrl, serviceRoleKey)}
在 .env 文件中添加:
SUPABASE_URL=your_project_urlSUPABASE_ANON_KEY=your_anon_key# 服务端密钥通过运行时注入(如通过 Nuxt3 的 runtimeConfig)
在 nuxt.config.ts 中配置:
export default defineNuxtConfig({runtimeConfig: {supabaseServiceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY || '',public: {supabaseUrl: process.env.SUPABASE_URL || '',supabaseAnonKey: process.env.SUPABASE_ANON_KEY || ''}}})
在组件或 API 路由中查询数据:
// 组件中直接使用(需处理异步)<script setup lang="ts">const { data: posts } = await useAsyncData('posts', async () => {const { data, error } = await supabase.from('posts').select('*')if (error) throw errorreturn data})</script>// 或通过 API 路由(推荐)// server/api/posts.get.tsexport default defineEventHandler(async (event) => {const { data, error } = await supabase.from('posts').select('*')if (error) throw createError({ statusCode: 500, message: error.message })return data})
// 组件中提交表单const submitForm = async () => {const { error } = await supabase.from('posts').insert({title: 'Nuxt3 实战',content: '配置 Supabase 数据库...'})if (error) alert('提交失败')}// API 路由示例// server/api/posts.post.tsexport default defineEventHandler(async (event) => {const body = await readBody(event)const { error } = await supabase.from('posts').insert(body)if (error) throw createError({ statusCode: 500, message: error.message })return { success: true }})
Supabase 支持 PostgreSQL 的 LISTEN/NOTIFY 机制,可通过以下方式实现实时更新:
// 组件中订阅onMounted(async () => {const { data } = supabase.from('posts').on('*', (payload) => {console.log('数据变更:', payload)// 更新本地状态}).subscribe()onUnmounted(() => {supabase.removeSubscription(data.subscription)})})
在 Supabase 控制台的 “Database” > “RLS Policies” 中,可为表配置细粒度权限。例如,仅允许用户访问自己的数据:
CREATE POLICY "Users can view their own profile" ON profilesFOR SELECT USING (auth.uid() = id);
对于需要身份验证的路由,使用 Nuxt3 的 useFetch 或 useAsyncData 时,需在服务端传递密钥:
// server/api/protected.get.tsexport default defineEventHandler(async (event) => {const config = useRuntimeConfig()const serviceSupabase = createServiceSupabase(config.supabaseServiceRoleKey)const { data, error } = await serviceSupabase.from('protected_data').select('*')if (error) throw createError({ statusCode: 403, message: '无权限' })return data})
统一封装错误处理逻辑:
// utils/errorHandler.tsexport const handleSupabaseError = (error: any) => {switch (error.code) {case 'PGRST116': return '资源不存在'case '42501': return '权限不足'default: return '服务器错误,请稍后重试'}}
Supabase 存储支持文件上传与 CDN 加速:
// 上传文件const { error } = await supabase.storage.from('avatars').upload(`user_${auth.user().id}`, file)// 生成访问 URLconst { data } = supabase.storage.from('avatars').getPublicUrl(`user_${auth.user().id}`)
在 Supabase 控制台的 “Database” > “Extensions” 中安装 pg_net 等扩展,或通过 SQL 创建触发器:
CREATE OR REPLACE FUNCTION notify_new_post()RETURNS TRIGGER AS $$BEGINPERFORM pg_notify('new_post', row_to_json(NEW)::text);RETURN NEW;END;$$ LANGUAGE plpgsql;CREATE TRIGGER post_triggerAFTER INSERT ON postsFOR EACH ROW EXECUTE FUNCTION notify_new_post();
通过以上配置,Nuxt3 项目可高效集成 Supabase 数据库,实现从数据存储到实时更新的全栈能力。实际开发中,建议结合 Supabase 的身份验证系统(如 GitHub OAuth)进一步完善用户管理流程。