返回 导航

其他

hangge.com

Vue3 - Supabase的集成与使用详解2(新增、修改、删除数据库数据)

作者:hangge | 2024-02-24 11:16
   前文介绍了 Vue 项目如何与 Supabase 后端服务平台进行集成,并且查询数据库中的数据(点击查看)。本文接着介绍如何对表中的数据进行新增、修改、删除等操作。 

三、新增、修改、删除数据库数据

1,准备工作

首先我们在 Supabase 上创建一张 book 表,并且插入一些初始数据:
drop table if exists book;

create table book (
  "id" bigint generated by default as identity primary key,
  "name" character varying,
  "price" numeric
);

INSERT INTO book ("name", "price") VALUES
  ('我与地坛', 29.00),
  ('失败者的春秋', 38.00),
  ('南北战争三百年', 35.00);

2,样例代码

我们在前文样例的基础上增加一些功能按钮,点击后调用 Supabase 客户端方法进行数据的新增、修改、删除等操作。
<script setup>
// 引入Vue 3的响应式引用(ref)和生命周期钩子(onMounted)
import { ref, onMounted } from 'vue'
 
// 引入Supabase客户端实例
import { supabase } from './lib/supabaseClient'
 
// 创建一个响应式的引用(ref)用于存储书籍数据
const books = ref([])
 
// 查询书籍
async function getBooks() {
  // 使用Supabase实例的select方法从'book'表中获取所有数据
  const { data } = await supabase.from('book').select()
 
  // 将查询结果更新到books引用中
  books.value = data
}

// 新增一本书籍
async function addOneBook() {
  await supabase.from('book').insert({ name: `新书籍${getRandNum()}`, price: getRandNum()})
  await getBooks()
}

// 新增三本书籍
async function addThreeBooks() {
  await supabase.from('book').insert([
   { name: `新书籍${getRandNum()}`, price: getRandNum()},
   { name: `新书籍${getRandNum()}`, price: getRandNum()},
   { name: `新书籍${getRandNum()}`, price: getRandNum()}
  ])
  await getBooks()
}

// 更新书籍
async function updateBook() {
  // 更新最后一条数据
  if (books.value.length > 0) {
    const lastBook = books.value[books.value.length - 1];
    await supabase.from('book')
      .update({ name: `新书籍${getRandNum()}`, price: getRandNum()}).eq('id', lastBook.id)
    await getBooks()
  }
}

// 删除书籍
async function deleteBook() {
  // 删除最后一条数据
  if (books.value.length > 0) {
    const lastBook = books.value[books.value.length - 1];
    await supabase.from('book').delete().eq('id', lastBook.id)
    await getBooks()
  }
}

// 插入或更新书籍
async function upsertBook() {
  await supabase.from('book')
    .upsert({ id: 100, name: `新书籍${getRandNum()}`, price: getRandNum()})
  await getBooks()
}

// 生成一个介于10(包含)和 100(不包含)之间的随机整数
function getRandNum() {
  return Math.floor(Math.random() * 90) + 10;
}
 
// 在组件被挂载后(mounted)执行getBooks函数,获取并更新书籍数据
onMounted(() => {
  getBooks()
})
</script>
 
<template>
  <div>
    <button class="action-button" @click="addOneBook">新增一本书籍</button>
    <button class="action-button" @click="addThreeBooks">新增三本书籍</button>
    <button class="action-button" @click="updateBook">更新最后一本书</button>
    <button class="action-button" @click="deleteBook">删除最后一本书</button>
    <button class="action-button" @click="upsertBook">插入或更新书籍</button>
  </div>
  <!-- 展示书籍数据的无序列表 -->
  <ul class="book-list">
    <li v-for="book in books" :key="book.id">
      {{ book.name }} (编号:{{ book.id }},价格:{{ book.price }})
    </li>
  </ul>
</template>

<style scoped>
  .action-button {
    margin-right: 5px; /* 设置按钮之间的外边距 */
  }

  .book-list {
    margin-top: 20px; /* 设置书籍列表上方的外边距 */
    padding: 0; /* 移除列表的内边距 */
  }

  .book-list li {
    margin-bottom: 8px; /* 设置每本书之间的外边距 */
  }
</style>

3,运行测试

(1)页面打开后首先会自动加载 book 表中的所有数据。

(2)点击“新增一本书籍”按钮,会向数据库中插入一本具有随机名称和价格的新书籍,并刷新显示所有书籍的列表。

(3)点击“新增三本书籍”按钮,会向数据库中插入三本具有随机名称和价格的新书籍,并刷新显示所有书籍的列表。

(4)点击“更新最后一本书”按钮,会更新数据库中最后一本书籍的名称和价格为随机值,并刷新显示所有书籍的列表。

(5)点击“删除最后一本书”按钮,会从数据库中删除最后一本书籍,并刷新显示所有书籍的列表。

(6)点击“插入或更新书籍”按钮,会向数据库中插入具有指定 id100、随机名称和价格的新书籍。

  • 如果已存在相同 id 的书籍则会更新其名称和价格,并刷新显示所有书籍的列表。

附:CORS policy 跨域问题解决

(1)如果调用 Supabase 官方在线服务接口报跨域问题的话,可以安装“Allow CORS: Access-Control-Allow-Origin”这个 Chrome 浏览器插件解决:

(2)安装后可能会遇到新增、删除接口都能正常调用,而更新时仍然报跨域请求被阻止问题:
Access to fetch at 'https://hucdsynwgldpummggxva.supabase.co/rest/v1/book?id=eq.8' from origin 'http://localhost:5173' has been blocked by CORS policy: Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.

(3)这是由于更新调用的是 PATCH 请求,插件默认没有设置对该方法对放行。打开插件的配置页面:

(4)在顶部输入框添加一个“PATCH”值,并勾选下面的“Allow PATCH method”复选框,然后保存退出即可。
评论

全部评论(0)

回到顶部