
前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载导读本文聚焦 VueUse 生态中vueuse/rxjs集成包的核心入口函数from与fromEvent。它们把 RxJS 的from()、fromEvent()包装为可以接收 Vueref的形式从而让 RxJS 的 Observable 流与 Vue 3 的响应式系统无缝衔接。读完本文你将掌握如何用from(ref)把响应式数据转换为事件流、如何用fromEvent(ref)自动订阅组件挂载后出现的 DOM 元素以及如何借助toObserver、useSubscription完成 Vue 与 RxJS 之间的双向数据流管理。一、vueuse/rxjs 是什么vueuse/rxjs是 VueUse 的一个官方集成包add-on其定位是让 RxJS 以「自然而然」的方式融入 Vue 3 的响应式世界。根据 packages/rxjs/package.json 的描述它Enables RxJS reactive functions in Vue版本号为15.0.0对rxjs的 peer 依赖要求为6.0.0对vue的 peer 依赖要求为^3.5.0。整个包的入口在 packages/rxjs/index.ts它统一导出了 7 个 APIfrom/fromEvent本文的主角RxJS 工厂函数的 ref 友好包装toObserver把ref转换为 RxJS Observer 的糖函数useObservable/watchExtractedObservable订阅 Observable 并回填到响应式状态useSubject在 Subject 与 ref 之间双向绑定useExtractedObservable从多个 composable 中提取出 ObservableuseSubscription安全托管 RxJS Subscription 的生命周期安装方式依据 packages/rxjs/README.mdnpm i vueuse/rxjs rxjs二、from让 ref 变成 Observable 流2.1 函数签名与核心思路from的核心签名见 packages/rxjs/from/index.tsexport function fromT(value: ObservableInputT | RefT, watchOptions?: WatchOptions): ObservableT它的设计哲学非常简洁当传入的是 Vueref时不走 RxJS 的from而是用 Vue 的watch在值变化时向订阅者next()当传入的是标准的 RxJSObservableInput数组、Promise、可迭代对象、另一个 Observable 等时原样交给 RxJS 的from()处理。对应源码if (isRefT(value)) return new Observable(subscriber watch(value, val subscriber.next(val), watchOptions)) return fromRxjs(value)也就是说from(count)得到的 Observable每次count.value被修改流中就会推出一条新数据。这使得 ref 成为了 RxJS 管道中的数据源。2.2 Watch Options控制发流时机当from收到 ref 时第二个参数是 Vue 原生的WatchOptions直接透传给watch。文档中给出的可选项如下OptionTypeDescriptionimmediatebooleanEmit the current value immediatelydeepbooleanDeeply watch nested objectsflushpre \| post \| syncTiming of the callback flushimmediate: trueObservable 一被订阅就立刻发出 ref 的当前值相当于给流一个初始值避免下游算子如withLatestFrom因为还没有任何值而收不到组合数据deep: true当 ref 指向嵌套对象时深度监听内部属性变化也会触发发流flush控制回调的刷新时机默认pre组件更新前可改为sync以获得同步发流或post延后到更新后。值得强调的是由于实现直接复用 Vue 的watch回调在执行时不会产生新的 ref 依赖收集副作用——它只是把变化转发给 RxJS 的subscriber.next()订阅关系由 Observable 内部维护。三、fromEvent自动跟随元素的 ref 变化3.1 解决的问题在 Vue 3 中模板引用template ref在组件挂载前是null挂载后才指向真实 DOM。如果用原生 RxJS 的fromEvent你必须在onMounted之后手动绑定事件还要处理元素被v-if卸载、重新挂载等场景。fromEvent的 ref 版本把这些脏活全部自动化。3.2 函数签名与实现细节签名见 packages/rxjs/from/index.tsexport function fromEventT extends HTMLElement | null(value: MaybeRefT, event: string): ObservableEvent实现逻辑分为三条路径传入 refwatch监听元素引用变化使用immediate: true立即检查一旦拿到真实的HTMLElement就调用 RxJS 原生fromEvent建立内部订阅并把该订阅add到外层 Observable 的订阅树上当元素引用改变例如旧元素被v-if移除、新元素挂载先innerSub?.unsubscribe()取消旧订阅再绑定新元素传入 null直接抛出错误The value isnull, and it should be an HTMLElement.避免静默失效传入真实元素等价于原生fromEvent(element, event)零开销透传。关键源码片段return new Observable((subscriber) { let innerSub: Subscription | undefined return watch(value, (element) { innerSub?.unsubscribe() if (element instanceof HTMLElement) { innerSub fromEventRx(element, event).subscribe(subscriber) subscriber.add(innerSub) } }, { immediate: true }) })注意其中的细节watch返回的停止函数被用作 Observable 的 teardown 逻辑也就是说当订阅被取消时Vue 的 watcher 也会被同步停掉不会残留监听器。3.3 典型用法import { fromEvent, useSubscription } from vueuse/rxjs import { useTemplateRef } from vue const button useTemplateRef(buttonRef) // 当 button 元素可用时自动订阅 useSubscription( fromEvent(button, click).subscribe(() { console.log(clicked!) }) )由于useTemplateRef返回的是响应式 ref元素挂载后fromEvent内部 watcher 立即捕获到真实 DOM 并建立事件流组件卸载时事件流随订阅一起被清理。四、配合 toObserver 与 useSubscription 实现完整闭环4.1 toObserverref 直接当 Observer 用在管道末端你既可以手写subscribe(val (count.value val))也可以使用toObserver源码见 packages/rxjs/toObserver/index.tsexport function toObserverT(value: RefT): NextObserverT { return { next: (val: T) { value.value val }, } }它把 ref 包装成只关心next事件的 Observer每次流发出新值就写回ref.value让响应式状态与 RxJS 数据流实现双向打通。4.2 useSubscription生命周期托管useSubscription见 packages/rxjs/useSubscription/index.ts接受任意实现了Unsubscribable接口的对象即 RxJS 的 Subscription并在当前作用域销毁时自动调用unsubscribe()。它内部复用了vueuse/shared的tryOnScopeDispose所以在setup()中使用时组件卸载前订阅会被自动清理从根源上避免内存泄漏。useSubscription( interval(1000) .subscribe(() { count.value console.log(count) }), )五、综合示例秒表累加器把上述 API 组合起来就得到了文档与 packages/rxjs/from/_demo.vue 中演示的经典场景——一个每秒累加、点击按钮即停止的计数器script setup langts import { from, fromEvent, toObserver, useSubscription } from vueuse/rxjs import { interval } from rxjs import { map, mapTo, takeUntil, withLatestFrom, } from rxjs/operators import { shallowRef, useTemplateRef } from vue const count shallowRef(0) const button useTemplateRef(button) useSubscription( interval(1000) .pipe( mapTo(1), // 点击 stop 按钮即终止整个流 takeUntil(fromEvent(button, click)), // 每轮累加前先读取当前 countimmediate 保证有初始值 withLatestFrom(from(count, { immediate: true, deep: false, })), map(([curr, total]) curr total), ) .subscribe(toObserver(count)), ) /script template div button clickcount count is: {{ count }} /button button refbutton stop /button /div /template这段示例的管道语义值得逐行拆解interval(1000).pipe(mapTo(1))每秒产生一个值1takeUntil(fromEvent(button, click))用 ref 版fromEvent监听stop按钮只要按钮可用组件挂载后就会建立监听一旦点击就结束整条流而无需关心按钮 ref 何时就绪withLatestFrom(from(count, { immediate: true, deep: false }))每次 tick 时读取当前count的最新值immediate: true保证第一次 tick 时count已有初始值可组合map(([curr, total]) curr total)把每秒新增 1累加到count上subscribe(toObserver(count))把结果写回count.value驱动模板更新。整个过程完全不需要手动onMounted、onBeforeUnmount或显式管理元素引用from/fromEvent的 ref 感知能力把 Vue 的响应式生命周期与 RxJS 的流式管线无缝对齐。六、在更大流程中延伸使用如果你需要在更复杂的业务流中继续复用这套能力from/fromEvent还可以与包内其他 API 组合。例如在 packages/rxjs/README.md 的示例中fromEvent(button, click)被接进useObservable配合ajax.getJSON实现点击按钮 → 并发拉取文章与评论的数据加载管线import { from, fromEvent, useObservable } from vueuse/rxjs import { forkJoin, of } from rxjs import { ajax } from rxjs/ajax import { concatAll, map, mergeMap, pluck, scan, take } from rxjs/operators import { useTemplateRef } from vue const button useTemplateRef(buttonRef) const posts useObservable( fromEvent(button, click).pipe( mergeMap(() ajax.getJSON(${BASE_URL}/posts).pipe( concatAll(), take(4), mergeMap(({ id, userId, title }) forkJoin({ id: of(id), comments: ajax.getJSON(${BASE_URL}/posts/${id}/comments).pipe( map(comments comments.length), ), username: ajax.getJSON(${BASE_URL}/users/${userId}).pipe( pluck(username), ), }), 2), scan((acc, curr) [...acc, curr], []), )), ), )此时posts是一个响应式 ref页面渲染的复杂数据管线依旧由 RxJS 掌控而 Vue 只负责消费最终结果。七、小结API核心能力源码位置from接受ObservableInput或 Vuerefref 变化即发流支持 WatchOptionspackages/rxjs/from/index.tsfromEvent接受元素 ref自动订阅/取消订阅挂载后的 DOM 元素事件packages/rxjs/from/index.tstoObserver把 ref 包装成只写next的 Observerpackages/rxjs/toObserver/index.tsuseSubscription作用域销毁时自动 unsubscribe防内存泄漏packages/rxjs/useSubscription/index.tsfrom与fromEvent是vueuse/rxjs连接 Vue 与 RxJS 两套反应式系统的接线端子一个把响应式状态变成数据流一个把 DOM 事件变成数据流。理解了它们内部对watch与原生 RxJS 工厂函数的桥接方式你就能在 Vue 组件中放心地使用 RxJS 的全部操作符能力同时保持 Vue 模板与响应式状态的一致性。相关源码均可直接在仓库中查阅from 实现、toObserver 实现、useSubscription 实现。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐airi 项目实战用 vueuse/rxjs 的 from 与 fromEvent 打通 Vue 响应式与 RxJS 流airi 项目实战用 vueuse/rxjs 的 from 与 fromEvent 打通 Vue 响应式与 RxJS 流 本篇指南以 .agents/skiAI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染MXNet 符号式 Faster R-CNN 实战指南基于 example/rcnn 的推理、训练与源码解析MXNet 符号式 Faster R CNN 实战指南基于 example/rcnn 的推理、训练与源码解析 本指南面向希望在 Apache MXNet 上快前端airi 前端响应式流实战用 VueUse toObserver 让 RxJS Observable 直接写入 Vue refairi 前端响应式流实战用 VueUse toObserver 让 RxJS Observable 直接写入 Vue ref toObserver 是 VuAI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染上一篇OpenShell GPU 环境 CUDA 基础工作负载验证cuda-basic实战指南下一篇Intel RealSense SDK深度图像后处理滤镜从噪声抑制到工业级3D数据优化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考