RxJS结合vue-rx, Akita的介绍和使用
RxJS
介绍: 解决异步事件。它将一切数据包括HTTP请求,DOM事件或者普通数据等包装成流的形式,然后利用强大丰富的操作符(Operators )对流进行处理,使得用户可以用同步编程的方式处理异步数据。
基本概念:Observable 类似于函数声明,subscribe类似于函数调用,调用时传入回调函数Observable 对象来执行,执行后的返回值称为Subscription ,可以停止后续Observable 的执行
Observable (可观察对象): 。是一可观察序列,简单来说数据就在Observable中流动,用户可以使用各种operator对流进行处理。
//create方法创建一个Observable
var observable = Observable.create(function(observer) { observer.next('Jerry'); observer.next('Anna');})// subscribe订阅 observable
console.log('start');
observable.subscribe(function(value) {console.log(value);
})
console.log('end');// 输出
start
Jerry
Anna
end
Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值,其包括以下三个方法
Next – 表示数据正常流动,没有出现异常
Error – 表示流中出错,可能是运行出错,http报错等
Complete – 表示流结束,不再发射新的数据
1、 要使用观察者,需要把它提供给Observable的subscribe方法。
2、 在一个流的生命周期中,error和complete只会触发其中一个,可以有多个next(表示多次发射数据),直到complete或者error。
console.log('just before subscribe');const observe = {next: x => console.log('got value ' + x),error: err => console.error('something wrong occurred: ' + err),complete: () => console.log('done'),};// 订阅这个 observable// 只有在订阅之后,才会在流Observable变化的时候,调用observer提供的方法,并通知它observable.subscribe(observe);console.log('just after subscribe');// 输出just before subscribegot value 1got value 2got value 3just after subscribegot value 4done
Subscription (订阅): 表示 Observable 的执行,Subscription基本上只有一个unsubscribe()函数,这个函数用来释放资源或取消Observable执行,清理由Subscription占用的资源。
let subscription = observable.subscribe(observe);setTimeout(() => {subscription.unsubscribe();}, 1000);
Operators (操作符):
操作符是Observable类型上的方法,用来处理集合。当操作符被调用时,它们不会改变已经存在的Observable实例。相反,它们会返回一个新的Observable,它的subscription逻辑基于第一个Observable。
其实部分操作符从功能来讲可能会觉得区别不太大,区分起来也比较困难,我们可以查阅它们的弹珠图来方便我们区分。
结合vue-rx的使用
安装并配置vue-rx的依赖包
yarn add rxjs
yarn add vue-rx
//main.js文件
import VueRx from "vue-rx";
Vue.use(VueRx);
vue-rx会新增一个钩子函数subscriptions,和vue的data类似的使用;以及用来存放事件的一个domStreams数组
事件的使用:
<template><ul><li v-for="(num, index) in numList" :key="index" v-stream:click="{subject: getNum$,data: {'index': index,'num': num}}">{{ num }}</li></ul><p>点击的数字为:{{ num$.index }}</p><p>点击的数字下标为:{{ num$.num }}</p>
</template>
<script>import { Observable } from 'rxjs'export default {name: 'HelloWorld',data () {return {numList: [1, 2, 3]}},domStreams: ['getNum$',],subscriptions() {return {num$: this.getNum$// 从传入的对象中获取key为data的value,传入下一个operator.pluck('data').map(data => data)// 因为视图引用了num$.index,所以这里要初始化num$为对象,避免报错.startWith({}) }}
</script>
关于switchMap、concatMap、exhaustMap的使用:
domStreams: ['getConcatMapCount$', 'getSwitchMapCount$', 'getExhaustMapCount$'],
subscriptions() {return {// 当你连续点击按钮多次获取数据时,cancatMap会将获取到的数据按队列发出concatMapCount$: this.getConcatMapCount$.concatMap(e => {return new Observable.from(this.getCount());}),// 当你连续点击按钮多次获取数据时,switchMap只会将最后一个点击发出的值发出,前面发出的值会被吞掉switchMapCount$: this.getSwitchMapCount$.switchMap(e => {return new Observable.from(this.getCount());}),// 当你连续点击按钮多次时,exhaustMap仅执行一次,在第一次值发出后,才可以继续点击下一次发出值exhaustMapCount$: this.getExhaustMapCount$.exhaustMap(e => {return new Observable.from(this.getCount())})}},methods: {getCount() {return new Promise((resolve, reject) => {this.count ++;setTimeout(() => {resolve(this.count);}, 1000);})}}
关于forkJoin的使用:
会在每个被合并的流都发出结束信号时发射一次数据,也就是只触发一次回调
methods: {getEmergencyMapData() {const $viewData = queryEmergencyViewMapData(this.$route.query.id).pipe(map(data => [data]),catchError(() => {return of([]);}));const $viewData2 = queryEmergencyIconpointMapData(this.$route.query.id).pipe(map(data => [data]),catchError(() => {return of([]);}));const $viewData3 = queryEmergencyDecisionMapData(this.$route.query.id).pipe(map(data => [data]),catchError(() => {return of([]);}));//同时发送三个请求,将返回值组成一个新的数组forkJoin($viewData, $viewData2, $viewData3) .pipe(map(([view1, view2, view3]) => [...view1, ...view2, ...view3])tap(data => {console.log(data )})).subscribe(); //在methods中必须订阅了才会发送请求}}
结合vue-rx, Akita的使用
Akita介绍: Akita是一种基于RxJS的状态管理模式,它采用Flux中的多个数据存储和Redux中的不可变更新的思想,以及流数据的概念,来创建可观察的数据存储模型。
Akita的使用:
安装并配置Akita的依赖包
yarn add @datorama/akita
在src下新建store文件,目录结构如下
xxx.store.js: 存放所要管理的状态
import { createStore } from "@datorama/akita";const initialState = {//存放ui展示的变量,一般为布尔值UI: {isShowPlanPanel: false, //预案详情},//存放其他变量,字符串,数组,对象等selectPlanId: null, //预案id//层级比较复杂的地图对象viewer: null
};export const basisDataStore = createStore(initialState, {name: "basisData"
});
xxx.service.js: 操作store数据的方法的集合,比如对该数据的修改、增加、删除等等
import { basisDataStore } from "./basis-data.store";export function isShowPlanPanel(show) {basisDataStore.update(state => ({...state,UI: { ...state.UI, isShowPlanPanel: show }}));
}
export function setSelectPlanId(id) {basisDataStore.update(state => ({...state,selectPlanId: id}));
}/**** @param {*} viewer 更新地图viewer*/
export function updateViewer(viewer) {mapStore.update(state => {return {...state,viewer};});
}
/*** 获取地图viewer* 可以不通过xxx.query.js文件,直接通过getViewer获取viewer对象,但不能监听其变化*/
export function getViewer() {return mapStore.getValue().viewer;
}
xxx.query.js: 将store数据暴露给外部,方便组件的调用
import { createQuery } from "@datorama/akita";
import { basisDataStore } from "./basis-data.store";export const basisDataQuery = createQuery(basisDataStore);export const $isShowPlanPanel = basisDataQuery.select(state => state.UI.isShowPlanPanel
);
export const $selectPlanId = basisDataQuery.select(state => state.selectPlanId);
参数传递的顺序依次是:
1.、组件A调用service.js的方法,为selectPlanId和isShowPlanPanel赋值
import {setSelectPlanId,isShowPlanPanel} from "../../store/basis-data/basis-data.service";onClickRow(row) {isShowPlanPanel(true);setSelectPlanId(row.id);}
2、组件B在subscriptions钩子函数中监听selectPlanId和isShowPlanPanel的变化
import { $selectPlanId } from "../../store/basis-data/basis-data.query";
subscriptions() {return {isShowPlanPanel: $isShowPlanPanel,planData: $selectPlanId.pipe(mergeMap(planId => queryPlanDetails(planId )),//发送请求,获取详情map(data => {if (data) {//数据处理...return data}}))};},
RxJS结合vue-rx, Akita的介绍和使用相关推荐
- 基于Vue的Quasar Framework 介绍 这个框架UI组件很全面
基于Vue的Quasar Framework 介绍 这个框架UI组件很全面 基于Vue的Quasar Framework 中文网 http://www.quasarchs.com/ quasarfra ...
- vue使用,及指令介绍,计算属性/过滤器
目录 Vue是什么 vue的单页面原理 Vue的使用 指令介绍: v-if和 v-show的区别 v-on 事件绑定: v-bind 绑定属性 处理数组绑定 v-model双向数据绑定 created ...
- 【vue作业】vue实现海贼王网页介绍--动漫网站设计
1.引言 你是否有过相关设计结课作业,课程设计无处下手,网页要求的总数量太多?没有合适的模板?数据库,java,python,vue,html作业复杂工程量过大?毕设毫无头绪等等一系列问题.你想要解决 ...
- Vue前端组件库介绍
kb-vue-components 组件库平台介绍 这里汇集大家常用的Vue组件, 并提供相应组件的使用教程. 方便你找到适合自己的组件,并快速上手使用. 开源项目地址: kb-vue-compone ...
- Vue 防抖节流 详细介绍(面试常客、去繁从简、性能优化)
本文主要介绍js中的防抖和节流以及在vue项目中如何使用它们来达到性能优化的目的. 前置知识点:js.闭包.es6.vue等. 使用背景: 很多场景下,页面具有交互性,免不了会触发一些事件以及发送一些 ...
- java英语单词学习网站 Vue项目源码介绍
本软件是一款高智能化的英语学习软件,具备查阅复习内容,复习进度,以及复习提醒等功能:还需具有复习汇总等功能.用户可无限扩充自己的词库,能随心所欲地制作出适合自己的词库,达到快速记单词,读音,词义的效果 ...
- Vue后台管理系统模板介绍
介绍:Vue.js 是一个目前比较流行的前端框架,今天给大家推荐几款基于 Vue 的后端管理的框架.目前比较流行和 Vue 搭配的 UI组件 有Element-UI.iview.Bootstrap-V ...
- vue项目结构目录介绍
一:目录结构介绍 二:项目介绍 build 文件夹 及 子目录 这里面是一些webpack的配置,主要用于项目打包时的一些设置.这里不去更详细的深入,相关的文件及配置会在后面用到时在详细的介绍. co ...
- Vue项目目录结构介绍(三)
前言 本章我们会对一个 Vue 项目的目录结构进行讲解,解释各子目录以及文件的作用,前端的模块化,Vue 单文件组件规范等. 1.基础目录和文件介绍 在上一章,我们通过 vue-cli 创建了一个新的 ...
最新文章
- python中构造方法可以被继承吗_python – 类继承:构造函数应该兼容吗?多重继承的情况?...
- JAVA 边界布局管理器
- MST(最小生成树)的构造
- arcgis 4.x graphicslayer点击事件_ArcGis中X、Y值的巧用方法小记
- 3d max用不同目标做关键帧_3D动画制作流程大解析
- KGDiscreetAlertView
- “狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
- 免费还能商用的视频素材,拿走不谢。
- 计算机cpu intel,intel CPU后面带F是什么意思?Intel处理器后面带“F”含义详解
- 区块链十年一梦:有人辞官归故里,有人星夜来赶考
- appdesigner生成exe文件并转移至不上网机
- 转载:一个程序员的顿悟
- c执行cmd pdf2swf_SWFTOOLS PDF2SWF 参数详解
- rsync同步+inotify实时同步部署
- 抖音视频突然播放量少了很多,抖音限流怎么查看?
- python绘制动态心电图_东软医院收费端使用手册.doc
- iterm 主题颜色配置
- day21-办公自动化:利用Python发邮件
- 20190724杭电多校第二场
- 数仓第5篇:『数据魔法』ETL