前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统

本文涉及的产品
资源编排,不限时长
无影云电脑个人版,1个月黄金款+200核时
无影云电脑企业版,4核8GB 120小时 1个月
简介: 本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。

Meteor 3.0 是一个功能强大的全栈 JavaScript 框架,特别适合实时应用程序的开发。它的核心机制之一就包括发布-订阅(Publish-Subscribe)模型,它允许服务器端发布数据,客户端订阅并实时更新。本文将介绍如何在 Meteor 3.0 中使用 publish-subscribe,包括简单发布、自定义发布,以及客户端的订阅和数据读取流程。

前文提要:开发环境的搭建 -全局安装或使用容器镜像容器化开发环境下的meteor工程架构解析运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例RPC方法注册及调用-更轻量的服务接口提供方式

1. 服务器端:publish 数据源

1.1 简单发布(返回 cursorcursor[]

在服务器端,发布数据非常简单。首先,你可以通过 Meteor.publish 来定义一个数据发布函数,该函数通常返回一个 MongoDB 集合的查询游标(cursor)。这个游标代表服务器向客户端发布的数据集。以发布一个简单的 Posts 集合为例:

// posts.js (服务器端代码)
import {
    Meteor } from 'meteor/meteor';
import {
    Posts } from '/imports/api/posts.js';

Meteor.publish('allPosts', function () {
   
  // 返回一个 cursor 对象,客户端可以订阅该发布源
  return Posts.find();
});

上面的代码会将 Posts 集合中的所有数据发布到客户端。客户端订阅后会自动接收到这些数据。

你也可以返回一个数组,其中包含多个游标。例如:

Meteor.publish('multipleCollections', function () {
   
  return [
    Posts.find(),
    Comments.find(),
  ];
});

这种方式适合在一次发布中返回来自多个集合的数据。

1.2 自定义发布(使用 added / changed / removed / stop 方法)

有时候你可能需要更灵活的控制,像控制数据发布的具体时机或内容。这时你可以使用 addedchangedremoved 以及 stop 方法来手动管理数据的发布。

自定义发布的典型例子是只发布部分数据,或者根据某些复杂的逻辑来动态发布。如下示例,发布一个用户拥有的所有 Tasks 集合中的任务:

// tasks.js (服务器端代码)
import {
    Meteor } from 'meteor/meteor';
import {
    Tasks } from '/imports/api/tasks.js';

Meteor.publish('userTasks', function () {
   
  const self = this;
  const userId = self.userId;

  if (!userId) {
   
    self.ready();
    return;
  }
// meteor的minimongo的find返回一个cursor,是可观察的;
// 除了数据集合,最常用的还包括订阅redis或者mq的数据
  const handle = Tasks.find({
    owner: userId }).observeChanges({
   
    added(id, fields) {
   
      // 这个tasks就是发布到前端哪个数据集合
      self.added('tasks', id, fields);
    },
    changed(id, fields) {
   
      self.changed('tasks', id, fields);
    },
    removed(id) {
   
      self.removed('tasks', id);
    },
  });

  self.ready();

  self.onStop(function () {
   
    handle.stop();
  });
});

在此示例中,使用 observeChanges 来监听数据库的变化并调用 addedchangedremoved,从而手动控制数据的发布。

2. 客户端:subscribe 订阅并读取数据

2.1 订阅与传参

在客户端,你可以使用 Meteor.subscribe 来订阅服务器端的发布源。对于简单的发布,订阅不需要任何参数;但对于自定义发布,你可以传递一些参数来过滤数据。例如,订阅上文中的 allPosts 数据源:

// client.js (客户端代码)
Meteor.subscribe('allPosts');

对于带参数的订阅,如根据用户 ID 来订阅特定用户的任务:

Meteor.subscribe('userTasks');

在订阅时还可以传递动态参数,例如只订阅特定状态的任务:

Meteor.subscribe('userTasks', {
    status: 'completed' });

2.2 从 MiniMongo 中读取数据并实时更新

在客户端订阅成功后,数据会被同步到客户端的 MiniMongo 数据库中。你可以使用 Mongo.Collection#find() 方法来从 MiniMongo 中检索数据。

// client.js (客户端代码)
import {
    Posts } from '/imports/api/posts.js';

Tracker.autorun(() => {
   
  const postsCursor = Posts.find();
  postsCursor.forEach(post => {
   
    console.log(post);
  });
});

通过 Tracker.autorun 包裹查询,你可以确保每当数据发生变化时,UI 自动重新渲染。例如,你可以将其绑定到一个模板或 React 组件中,实时显示更新的数据。

3. 使用 mapCursor 将 MiniMongo 的 cursor 转化为 Vue 3 响应式数组

在 Meteor 3.0 中,使用 autorun 可以自动跟踪数据的变化。而在 Vue 3 中,响应式系统是通过 reactive 实现的。为了在 Vue 3 的 setup 函数中使用 Meteor 的数据订阅,我们可以定义一个方法 mapCursor,将 Meteor 的 MiniMongo 游标(cursor)转化为 Vue 3 的响应式数组。

3.1 方法设计

我们将定义一个名为 mapCursor 的函数,它接收一个 Meteor 的 cursor,例如 Tasks.find({}),然后利用 Tracker.autorun 来监听游标变化。每当游标中的数据发生变化时,我们将更新 Vue 3 的 reactive 数组。并且,这个方法适合在 Vue 3 的 setup 函数中使用,能够在组件卸载时自动停止 autorun

3.2 代码实现

import {
    reactive, onUnmounted } from 'vue';
import {
    Tracker } from 'meteor/tracker';

export function mapCursor(cursor) {
   
  // 创建一个响应式数组
  const reactiveArray = reactive([]);

  // 使用 autorun 监控 cursor 的变化
  const computation = Tracker.autorun(() => {
   
    // 获取游标中的数据
    const data = cursor.fetch();

    // 清空 reactiveArray 并用新的数据替换
    reactiveArray.length = 0;  // 清空数组
    data.forEach(item => {
   
      reactiveArray.push(item);  // 添加新的数据
    });
  });

  // 使用 onUnmounted 确保组件卸载时停止 autorun
  onUnmounted(() => {
   
    computation.stop();
  });

  // 返回响应式数组
  return reactiveArray;
}

3.3 方法说明

  1. reactiveArray 使用 Vue 3 的 reactive 方法创建一个响应式数组,用来存储 cursor 的数据。

  2. Tracker.autorun 用于监控 cursor 的变化。每当 MiniMongo 中的数据发生变化时,它会自动运行,将最新的数据同步到 reactiveArray 中。

  3. 清空并重新填充数组: 当游标中的数据发生变化时,我们先清空 reactiveArray,然后用新的数据重新填充它。

  4. onUnmounted 确保当组件卸载时停止 autorun 监控,避免内存泄漏。

  5. 返回值: 返回的是一个 Vue 3 的响应式数组,这个数组会随着 MiniMongo 中数据的变化而自动更新。

3.4 在 Vue 3 中使用 mapCursor

该方法设计为在 Vue 3 的 setup 函数中使用,下面是如何在组件中使用这个方法的示例:

<template>
  <div>
    <h2>任务列表</h2>
    <ul>
      <li v-for="task in tasks" :key="task._id">{
   {
    task.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import {
    Tasks } from '/imports/api/tasks.js';
import {
    mapCursor } from '/imports/utils/mapCursor.js';

// 订阅 Tasks 数据
const tasks = mapCursor(Tasks.find({
   }));
</script>

总结

Meteor 3.0 的发布-订阅模型使得开发实时应用非常高效。服务器端可以通过简单发布或自定义发布来灵活地控制数据的发布,客户端则可以通过订阅获取数据,并通过 Tracker.autorun 等机制实现自动化的 UI 更新。这种架构能够确保客户端总是与服务器端的数据保持同步,不需要定时或者在某个时机去获取最新数据。

相关文章
|
15天前
|
资源调度 前端开发 JavaScript
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第10天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤,包括安装依赖、创建混淆脚本、修改 `package.json` 脚本命令、构建项目并执行混淆,以及在 HTML 文件中引用混淆后的文件。通过这些步骤,可以有效提高代码的安全性。
|
2月前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
2月前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
2月前
|
JSON 前端开发 数据格式
前端的全栈之路Meteor篇(五):自定义对象序列化的EJSON介绍 - 跨设备的对象传输
EJSON是Meteor框架中扩展了标准JSON的库,支持更多数据类型如`Date`、`Binary`等。它提供了序列化和反序列化功能,使客户端和服务器之间的复杂数据传输更加便捷高效。EJSON还支持自定义对象的定义和传输,通过`EJSON.addType`注册自定义类型,确保数据在两端无缝传递。
|
18天前
|
前端开发 JavaScript 安全
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第7天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤。包括项目准备、安装 `javascript-obfuscator`、配置 Vite 构建以应用混淆,以及最终构建项目进行混淆。通过这些步骤,可以有效提升前端代码的安全性,防止被他人轻易分析和盗用。
|
2月前
|
前端开发 安全 API
前端全栈之路Deno篇(三):一次性搞懂和学会用Deno 2.0 的权限系统详解和多种权限配置权限声明方式
本文深入解析了 Deno 2.0 的权限系统,涵盖主包和第三方包的权限控制机制,探讨了通过命令行参数、权限 API 和配置文件等多种权限授予方式,并提供了代码示例和运行指导,帮助开发者有效管理权限,提升应用安全性。
|
2月前
|
前端开发 JavaScript API
前端的全栈之路Meteor篇(完):关于前后端分离及与各框架的对比,浅析分离之下的潜在耦合
本文探讨了Meteor.js这一全栈JavaScript框架的特点与优势,特别是在前后端分离架构中的应用。Meteor通过共享数据结构和简化全栈开发流程,实现了前后端的紧密协作。文章还对比了其他全栈框架,如Next.js、Nuxt.js等,分析了各自的优势与适用场景,最后讨论了通过定义文档归属者和用户专有数据集简化后端构建及端云数据同步的方法。
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
142 2
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
44 0
|
2月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。