当前位置: 首页 > news >正文

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

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

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 确保组件卸载时停止 autorunonUnmounted(() => {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 更新。这种架构能够确保客户端总是与服务器端的数据保持同步,不需要定时或者在某个时机去获取最新数据。

写了这么几个章节,我发现自己忽略了一个开发环境的搭建章节,后续某个时间点再补上…先以其简单性吸引点人气,后期项目实战之前再介绍环境准备,其实也很简单

http://www.lryc.cn/news/453050.html

相关文章:

  • 自动驾驶系列—颠覆未来驾驶:深入解析自动驾驶线控转向系统技术
  • Webstorm 中对 Node.js 后端项目进行断点调试
  • VUE前后端分离毕业设计题目项目有哪些,VUE程序开发常见毕业论文设计推荐
  • 一、Spring Boot集成Spring Security之自动装配
  • 计数相关的题 Python 力扣
  • Express内置的中间件(express.json和express.urlencoded)格式的请求体数据
  • cmakelist加载Qt模块
  • 8-2.Android 任务之 CountDownTimer 编码模板(开启计时器、取消计时器)
  • Servlet的生命周期及用户提交表单页面的实现(实验报告)
  • 【Router】路由功能之IP过滤(IP Filter)功能(基于端口)介绍及实现
  • 数据结构_2.2、顺序表插入删除查找
  • 嵌入式C语言自我修养:编译链接
  • Mac制作Linux操作系统启动盘
  • PHP语言发展历程
  • Notepad++ 之 AndroidLogger插件
  • 开源2+1链动模式AI智能名片O2O商城小程序源码:线下店立体连接的超强助力器
  • 我为什么决定关闭ChatGPT的记忆功能?
  • 如何使用ssm实现中学生课后服务的信息管理与推荐+vue
  • 【分别为微服务云原生】9分钟ActiveMQ延时消息队列:定时任务的革命与Quartz的较量
  • 泛型编程--模板【C++提升】(特化、类属、参数包的展开、static、模板机制、重载......你想知道的全都有)
  • 安卓使用memtester进行内存压力测试
  • Dave Cheney: Go语言之禅
  • SpringMVC源码-AbstractUrlHandlerMapping处理器映射器将实现Controller接口的方式定义的路径存储进去
  • 满填充透明背景二维码生成
  • Python | Leetcode Python题解之第452题用最少数量的箭引爆气球
  • 代码随想录 | Day26 | 二叉树:二叉搜索树中的插入操作删除二叉搜索树中的节点修剪二叉搜索树
  • 使用Apifox创建接口文档,部署第一个简单的基于Vue+Axios的前端项目
  • TCP的第三次握手没有回复,会出现哪些问题现象
  • 【工具】arxiv_latex_cleaner 去除latex注释
  • macOS开发环境配置与应用开发