Vue3 - Supabase的集成与使用详解1(安装配置、查询数据库数据)
作者:hangge | 2024-02-23 09:11
Supabase 是一个开源的后端即服务(Backend-as-a-Service,BaaS)平台,提供了数据库、认证和实时推送等功能。通过 Vue 和 Supabase 的结合,我们可以构建出现代化的、具备实时数据能力的 Web 应用。本文将详细介绍如何在 Vue 3 项目中集成 Supabase,并进行表数据的查询。
一、安装配置
1,Supabase 准备工作
(1)Supabase 支持私有化部署,我们可以通过容器技术部署一个私有的 Supabase 服务来使用,具体可以参考我之前写的文章:
(2)当然我们也可以直接使用 Supabase 官方提供的在线服务,支持免费和付费使用方式。免费使用有一些限制的,但对于学习测试,或者简单的应用也是足够的。
- Supabase 官网地址:https://supabase.com/
(3)假设我们使用 Supabase 官方在线服务,登录 Supabase 控制台,创建一个新项目,然后在项目设置中找到 API 的地址和 API 密钥。这两个后面在 Vue 项目中需要用到。
(4)接着我们创建一张 book 书籍表:
(5)然后在该表中添加一些测试数据:
2,Vue 准备工作
(1)首先我们执行如下命令创建一个 Vue3 项目:
npm init vue@latest my-app
(2)接着进入项目文件夹,并安装 Supabase 客户端库:
cd my-app npm install @supabase/supabase-js
(3)在项目中创建一个 /src/lib 目录,创建一个名为 supabaseClient.js 的文件:
(4)supabaseClient.js 文件内容如下,使用 Supabase 上对应项目 URL 和公共 API(anon)密钥初始化 Supabase 客户端:
import { createClient } from '@supabase/supabase-js' export const supabase = createClient('https://hucdsynwgldpummggxva.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imh1Y2RzeW53Z2xkcHVtbWdneHZhIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDIxMjkwMDEsImV4cCI6MjAxNzcwNTAwMX0.ndfQkMSYvjtfvdK9lPza23tam6Pn4QKEaOpEEMKGMf0')
二、表数据的查询
1,基本查询
(1)将 App.vue 文件代码修改成如下,查询所有 book 表中的数据并展示到页面中:
<script setup> // 引入Vue 3的响应式引用(ref)和生命周期钩子(onMounted) import { ref, onMounted } from 'vue' // 引入Supabase客户端实例 import { supabase } from './lib/supabaseClient' // 创建一个响应式的引用(ref)用于存储书籍数据 const books = ref([]) // 定义异步函数,用于从Supabase查询书籍数据并更新books引用 async function getBooks() { // 使用Supabase实例的select方法从'book'表中获取所有数据 const { data } = await supabase.from('book').select() // 将查询结果更新到books引用中 books.value = data } // 在组件被挂载后(mounted)执行getBooks函数,获取并更新书籍数据 onMounted(() => { getBooks() }) </script> <template> <!-- 展示书籍数据的无序列表 --> <ul> <li v-for="book in books" :key="book.id"> {{ book.name }} (编号:{{ book.id }},价格:{{ book.price }}) </li> </ul> </template>
(2)运行结果如下:
2,带分页的查询
(1)查询时使用 range 方法可以构建对数值列进行范围查询的条件,该方法传入查询范围的起始值和结束值:
const { data } = await supabase.from('book').select().range(0,1)
(2)上面代码运行后只查询出 book 表的前两条数据:
3,带过滤条件的查询
(1)下面代码使用 Supabase 实例的 select 方法从 'book' 表中获取价格大于 30 的数据:
const { data } = await supabase.from('book').select().gt('price', 30)
(2)下面是一些常用的过滤器:
await supabase .from('book') .select("*") // 选择所有列(通配符) // Filters(过滤器) .eq('column', 'Equal to') // 等于(Equal to) .gt('column', 'Greater than') // 大于(Greater than) .lt('column', 'Less than') // 小于(Less than) .gte('column', 'Greater than or equal to') // 大于等于(Greater than or equal to) .lte('column', 'Less than or equal to') // 小于等于(Less than or equal to) .like('column', '%CaseSensitive%') // 类似(Like),区分大小写 .ilike('column', '%CaseInsensitive%') // 类似(iLike),不区分大小写 .is('column', null) // 是空值(Is null) .in('column', ['Array', 'Values']) // 在指定值数组中(In) .neq('column', 'Not equal to') // 不等于(Not equal to) // Arrays(数组) .cs('array_column', ['array', 'contains']) // 包含数组(array contains) .cd('array_column', ['contained', 'by']); // 被数组包含(contained by)
4,一对多关联查询
(1)这里假设我们再增加一个出版社 publisher 表,出版社与书籍为一对多关系。这次我们直接使用 SQL 语句创建表:
注意:book 上的外键是必须的,否则将无法关联查询。
drop table if exists book; drop table if exists publisher; create table publisher ( "id" bigint generated by default as identity primary key, "name" character varying ); create table book ( "id" bigint generated by default as identity primary key, "name" character varying, "price" numeric, "publisher_id" int references publisher ); INSERT INTO publisher ("id", "name") VALUES (1, '百花文艺出版社'), (2, '人民文学出版社'); INSERT INTO book ("name", "price", "publisher_id") VALUES ('我与地坛', 29.00, 1), ('失败者的春秋', 38.00, 2), ('南北战争三百年', 35.00, 1);
(2)Vue 代码修改如下,查询 book 表数据时增加了关联 publisher 表,并将结果打印出来:
<script setup> // 引入Vue 3的响应式引用(ref)和生命周期钩子(onMounted) import { ref, onMounted } from 'vue' // 引入Supabase客户端实例 import { supabase } from './lib/supabaseClient' // 创建一个响应式的引用(ref)用于存储书籍数据 const books = ref([]) // 定义异步函数,用于从Supabase查询书籍数据并更新books引用 async function getBooks() { // 使用Supabase实例的select方法从'book'表中获取价格大于30的数据 const { data } = await supabase.from('book').select(` id, name, price, publisher ( id, name ) `) console.log(data) // 将查询结果更新到books引用中 books.value = data } // 在组件被挂载后(mounted)执行getBooks函数,获取并更新书籍数据 onMounted(() => { getBooks() }) </script> <template> <!-- 展示书籍数据的无序列表 --> <ul> <li v-for="book in books" :key="book.id"> {{ book.name }} (编号:{{ book.id }},价格:{{ book.price }},出版社:{{ book.publisher.name }}) </li> </ul> </template>
(3)运行结果如下:
5,多对多关联查询
(1)这里假设我们再增加一个标签 tag 表,标签与书籍为多对多关系。我们使用如下 SQL 语句创建标签表和多对多关联的中间表:
DROP TABLE IF EXISTS tag_book_association; DROP TABLE IF EXISTS tag; CREATE TABLE tag ( "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "name" CHARACTER VARYING ); CREATE TABLE tag_book_association ( "tag_id" BIGINT REFERENCES tag, "book_id" BIGINT REFERENCES book, PRIMARY KEY ("tag_id", "book_id") ); INSERT INTO tag ("id", "name") VALUES (1, '文学'), (2, '历史'), (3, '自传'); INSERT INTO tag_book_association ("tag_id", "book_id") VALUES (1, 1), (3, 1), (2, 2), (3, 2), (2, 3);
(2)Vue 代码修改如下,查询 book 表数据是增加了关联 tag 表,并将结果打印出来:
<script setup> // 引入Vue 3的响应式引用(ref)和生命周期钩子(onMounted) import { ref, onMounted } from 'vue' // 引入Supabase客户端实例 import { supabase } from './lib/supabaseClient' // 创建一个响应式的引用(ref)用于存储书籍数据 const books = ref([]) // 定义异步函数,用于从Supabase查询书籍数据并更新books引用 async function getBooks() { // 使用Supabase实例的select方法从'book'表中获取价格大于30的数据 const { data } = await supabase.from('book').select(` id, name, price, publisher ( id, name ), tag ( id, name ) `) console.log(data) // 将查询结果更新到books引用中 books.value = data } // 在组件被挂载后(mounted)执行getBooks函数,获取并更新书籍数据 onMounted(() => { getBooks() }) </script> <template> <!-- 展示书籍数据的无序列表 --> <ul> <li v-for="book in books" :key="book.id"> {{ book.name }} (编号:{{ book.id }},价格:{{ book.price }},出版社:{{ book.publisher.name }}) <ul> <li v-for="tag in book.tag" :key="tag.id">{{ tag.name }}</li> </ul> </li> </ul> </template>
(3)运行结果如下:
全部评论(0)