返回 导航

其他

hangge.com

Vue3 - Supabase的集成与使用详解3(监听数据变化进行实时数据更新)

作者:hangge | 2024-02-26 08:50
    Supabase 不仅提供了强大的查询功能,还支持实时数据推送,使得应用能够实时响应数据库中的变化。在 Vue 中,我们可以通过监听 Supabase 中表的变化来实现实时的数据更新,下面通过样例进行演示。

三、监听数据变化进行实时数据更新

1,准备工作

(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)接着我们开启 book 表的 Realtime 功能,运行客户端实时侦听数据库更改。
 

2,样例代码

我们在前文样例的基础上增加增加了对 book 表数据新增数据事件的订阅,使其在监听到数据增加时会自动加载数据并刷新页面内容。
<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()

  // 订阅book数据插入事件消息
  supabase.channel('book-channel')
  .on(
    'postgres_changes',
    { event: 'INSERT', schema: 'public', table: 'book' },
    (payload) => {
      console.log('数据发送变化!', payload)
      // 重新加载数据
      getBooks()
    }
  )
  .subscribe()
})
</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)接着我们在 Supabase 控制页面上手动插入一条数据。

(3)由于 Vue 客户端这边已经订阅了 postgres_changes 实时事件,会感知到数据插入的变化。
 
(4)然后自动执行相应的动作,如重新获取并显示数据。

附:实时监听功能详细说明

1,所有监听事件

(1)监听所有事件:
supabase.channel('book-channel')
.on(
  'postgres_changes',
  { event: '*', schema: 'public', table: 'book' },
  (payload) => {
    console.log('数据发送变化!', payload)
    // 执行自定义的方法
    // ......
  }
)
.subscribe()

(2)监听插入事件:
supabase.channel('book-channel')
.on(
  'postgres_changes',
  { event: 'INSERT', schema: 'public', table: 'book' },
  (payload) => {
    console.log('数据发送变化!', payload)
    // 执行自定义的方法
    // ......
  }
)
.subscribe()

(3)监听更新时间:
supabase.channel('book-channel')
.on(
  'postgres_changes',
  { event: 'UPDATE', schema: 'public', table: 'book' },
  (payload) => {
    console.log('数据发送变化!', payload)
    // 执行自定义的方法
    // ......
  }
)
.subscribe()

(4)监听删除事件
supabase.channel('book-channel')
.on(
  'postgres_changes',
  { event: 'DELETE', schema: 'public', table: 'book' },
  (payload) => {
    console.log('数据发送变化!', payload)
    // 执行自定义的方法
    // ......
  }
)
.subscribe()

2,监听时添加额外条件

    我们可以通过 filter 属性指定额外的条件,即只监听满足条件的变化事件。比如下面只有在插入的书籍价格大于 50 时才触发相相应:
supabase.channel('book-channel')
.on(
  'postgres_changes',
  { 
    event: 'INSERT', schema: 'public', table: 'book',
    filter: 'price=gt.50'
  },
  (payload) => {
    console.log('数据发送变化!', payload)
    // 执行自定义的方法
    // ......
  }
)
.subscribe()
评论

全部评论(0)

回到顶部