ReactiveX 学习笔记(25)使用 RxJS + Vue.js 调用 REST API
JSON : Placeholder
JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站。
以下使用 RxJS6 + Vue.js 调用该网站的 REST API,获取字符串以及 JSON 数据。
- GET /posts/1
- GET /posts
- POST /posts
- PUT /posts/1
- DELETE /posts/1
所有 GET API 都返回JSON数据,格式(JSON-Schema)如下:
{
"type":"object",
"properties": {
"userId": {"type" : "integer"},
"id": {"type" : "integer"},
"title": {"type" : "string"},
"body": {"type" : "string"}
}
}
创建工程
# 安装 Vue CLI
$ npm install --global @vue/cli
# 创建新的应用程序 RxExample
$ vue create rx-example
# 选择 Manually select features
# 选择 Babel 和 TypeScript
$ cd rx-example
$ npm run serve
打开 Intellij IDEA, File / New / Project From Existing Sources...,然后选中工程所在文件夹
在向导的第1页选择 Create project from existing sources
完成向导后在点击 Finish 创建工程。
点击 Add Configurations, 点击 +npm
Name: Vue CLI Server
Scripts: serve
点击 OK 完成配置。
点击 Vue CLI Server 启动程序。
http://localhost:8080/ 可打开网页。
Post
在 src 文件夹下添加 post.ts,内容如下
export class Post {
userId!: number;
id!: number;
title!: string;
body!: string;
toString(): string {
return `Post {userId = ${this.userId}, id = ${this.id}, title = "${this.title}", body = "${this.body.replace(/\n/g, '\\n')}"}`;
}
}
安装 vue-typescript-inject
vue-typescript-inject 是一个在 Vue.js 中实现 DI(依赖注入) 的包。
使用这个包需要安装 vue-typescript-inject 和 reflect-metadata。
$ npm i vue-typescript-inject reflect-metadata
打开 tsconfig.json 在 compilerOptions 中
添加关于 emitDecoratorMetadata 的设定。
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
打开 main.ts 将其改为
import 'reflect-metadata';
import Vue from 'vue'
import App from './App.vue'
import VueTypeScriptInject from 'vue-typescript-inject';
Vue.config.productionTip = false;
Vue.use(VueTypeScriptInject); // register vue-typescript-inject
new Vue({
render: h => h(App),
}).$mount('#app');
安装 Rxios
访问 API 采用将 RxJS 和 axios 合为一体的 Rxios 组件,但是该组件尚未升级到 RxJS6。
这里我们只安装 RxJS 和 axios,然后直接以源码形式引入 Rxios,并将其升级到 RxJS6。
$ npm install axios rxjs
在 src 文件夹下添加 rxios.ts,内容如下
// https://github.com/davguij/rxios/blob/master/src/index.ts
// ported to rxjs6
import axios, { AxiosInstance, AxiosRequestConfig, AxiosPromise } from 'axios';
// import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
export interface rxiosConfig extends AxiosRequestConfig {
localCache?: boolean;
}
class rxios {
private _httpClient: AxiosInstance;
constructor(options: rxiosConfig = {}) {
this._httpClient = axios.create(options);
}
private _makeRequest<T>(method: string, url: string, queryParams?: object, body?: object) {
let request: AxiosPromise<T>;
switch (method) {
case 'GET':
request = this._httpClient.get<T>(url, {params: queryParams});
break;
case 'POST':
request = this._httpClient.post<T>(url, body, {params: queryParams});
break;
case 'PUT':
request = this._httpClient.put<T>(url, body, {params: queryParams});
break;
case 'PATCH':
request = this._httpClient.patch<T>(url, body, {params: queryParams});
break;
case 'DELETE':
request = this._httpClient.delete(url, {params: queryParams});
break;
default:
throw new Error('Method not supported');
}
return new Observable<T>(subscriber => {
request.then(response => {
subscriber.next(response.data);
subscriber.complete();
}).catch((err: Error) => {
subscriber.error(err);
subscriber.complete();
});
});
}
public get<T>(url: string, queryParams?: object) {
return this._makeRequest<T>('GET', url, queryParams);
}
public post<T>(url: string, body: object, queryParams?: object) {
return this._makeRequest<T>('POST', url, queryParams, body);
}
public put<T>(url: string, body: object, queryParams?: object) {
return this._makeRequest<T>('PUT', url, queryParams, body);
}
public patch<T>(url: string, body: object, queryParams?: object) {
return this._makeRequest<T>('PATCH', url, queryParams, body);
}
public delete(url: string, queryParams?: object) {
return this._makeRequest('DELETE', url, queryParams);
}
}
export {rxios, rxios as Rxios};
post 服务
在 src 文件夹下添加 post.service.ts,内容如下
import { Injectable } from 'react.di';
import { Observable, from } from 'rxjs';
import { map, mergeAll, take, tap } from 'rxjs/operators';
import { Post } from './post';
import { Rxios } from './rxios';
@Injectable
export class PostService {
private readonly http = new Rxios();
private readonly baseUrl = 'http://jsonplaceholder.typicode.com/';
constructor() {
this.getPostAsString().subscribe();
this.getPostAsJson().subscribe();
this.getPosts(2).subscribe();
this.createPost().subscribe();
this.updatePost().subscribe();
this.deletePost().subscribe();
}
private getPostAsString(): Observable<string> {
const url = `${this.baseUrl}posts/1`;
return new Rxios({transformResponse: undefined}).get<string>(url)
.pipe(
tap((result: any) => console.log(result)),
);
}
private getPostAsJson(): Observable<Post> {
const url = `${this.baseUrl}posts/1`;
return this.http.get<Post>(url)
.pipe(
map((result: any) => Object.assign(new Post(), result)),
tap((result: any) => console.log('' + result)),
);
}
private getPosts(n: number): Observable<Post> {
const url = `${this.baseUrl}posts`;
return from(this.http.get<Post[]>(url))
.pipe(
mergeAll(),
map((result: any) => Object.assign(new Post(), result)),
take(n),
tap((result: any) => console.log('' + result)),
);
}
private createPost(): Observable<string> {
const url = `${this.baseUrl}posts`;
return this.http.post(url, {
params: {
userId: 101,
title: 'test title',
body: 'test body',
}
})
.pipe(
map((result: any) => JSON.stringify(result)),
tap((result: any) => console.log(result)),
);
}
private updatePost(): Observable<string> {
const url = `${this.baseUrl}posts/1`;
return this.http.put(url, {
params: {
userId: 101,
title: 'test title',
body: 'test body',
}
})
.pipe(
map((result: any) => JSON.stringify(result)),
tap((result: any) => console.log(result)),
);
}
private deletePost(): Observable<string> {
const url = `${this.baseUrl}posts/1`;
return this.http.delete(url)
.pipe(
map((result: any) => JSON.stringify(result)),
tap((result: any) => console.log(result)),
);
}
}
- getPostAsString 方法取出第1个Post,返回字符串
- getPostAsJson 方法取出第1个Post,返回Post对象
- getPosts 方法取出前n个Post,返回n个Post对象
- createPost 方法创建1个Post,返回字符串
- updatePost 方法更新第1个Post,返回字符串
- deletePost 方法删除第1个Post,返回字符串
删除 HelloWorld 组件,即 src/components/HelloWorld.vue 文件。
打开 App.vue,将其改为
<template>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { PostService } from './post.service';
import { inject } from 'vue-typescript-inject';
@Component({
providers: [
PostService,
],
})
export default class App extends Vue {
@inject() postService!: PostService;
}
</script>
<style>
</style>
输出结果
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
{"params":{"userId":101,"title":"test title","body":"test body"},"id":101}
{"params":{"userId":101,"title":"test title","body":"test body"},"id":1}
{}
ReactiveX 学习笔记(25)使用 RxJS + Vue.js 调用 REST API的更多相关文章
- ReactiveX 学习笔记(26)使用 RxJS + React.js 调用 REST API
JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...
- ReactiveX 学习笔记(0)学习资源
ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
- vue.js 调用iOS原生方法,JavaScriptCore
1. 2. 3. 4.vue.js调用
- Vue.js 2.x API 知识梳理(一) 全局配置
Vue.js 2.x API 知识梳理(一) 全局配置 Vue.config是一个对象,包含Vue的全局配置.可以在启动应用之前修改指定属性. 这里不是指的@vue/cli的vue.config.js ...
- Vue.js 学习笔记之五:编译 vue 组件
正如上一篇笔记中所说,直接使用 ES6 标准提供的模块规范来编写 Vue 组件在很多情况下可能并不是最佳实践.主要原因有两个,首先是市面上还有许多并没有对 ES6 标准提供完全支持的 Web 浏览器, ...
- Dynamic CRM 2013学习笔记(九)CrmFetchKit.js介绍:Fetchxml、多表联合查询, 批量更新
CrmFetchKit.js是一个跨浏览器的一个类库,允许通过JavaScript来执行fetch xml的查询,还可以实现批量更新,分页查询等.目前已支持Chrome 25, Firefox 19 ...
- Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识
目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...
- Nodejs学习笔记(六)—Node.js + Express 构建网站预备知识
前言 前面经过五篇Node.js的学习,基本可以开始动手构建一个网站应用了,先用这一篇了解一些构建网站的知识! 主要是些基础的东西... 如何去创建路由规则.如何去提交表单并接收表单项的值.如何去给密 ...
随机推荐
- 46 Simple Python Exercises (前20道题)
46 Simple Python Exercises This is version 0.45 of a collection of simple Python exercises construct ...
- Ansible 之动态Inventory文件(二)
上篇主要讲解了Ansible 的安装和配置,并且根据不同的业务场景将服务器的信息存放在Ansible的Inventory中,其实存放这样的数据每次更新都需要我们自动的添加和删除,这样对于我们维护起来很 ...
- Btrace 拦截构造函数,同名函数
拦截方法: 1.普通方法 @OnMethod(clazz="", method="") 2.构造函数@OnMethod(claszz="" ...
- docker 限制container容器使用内存大小,不限制swap
docker update --memory 20g --memory-swap -1 96b14c546d98 参考:https://my.oschina.net/Kanonpy/blog/2209 ...
- QQ群成员发言次数统计(词云制作)
所用数据来自于之前的一篇博客: <QQ群成员发言次数统计(正则表达式版)> 链接:http://www.cnblogs.com/liyongzhao/p/3324026.html 1.首先 ...
- html5/h5课件如何制作?
随着flash逐渐被html5取代,很多教育机构都在面临着如何将自己的flash交互课件产品转换到html5版本的问题,最近遇到非常多的客户一上来就问我,flash课件能直接转成Html5课件么?答案 ...
- Javascript神器之webstorm
推荐个编辑器主题下载的一个网站. Color Themes 网址:http://color-themes.com [点这里直接跳转] 但是,只支持几个编辑器. 各种颜色搭配的主题,随你选择!我个 ...
- CentOS7用hostapd做radius服务器为WiFi提供802.1X企业认证
CentOS7用hostapd做radius服务器为WiFi提供802.1X企业认证 来源: https://www.cnblogs.com/osnosn/p/10593297.html 来自osno ...
- Windows10上桌面共享
Windows自带的桌面共享软件 命令行输入: Msra.exe
- Spring事件通知机制
在上图中,调用 getApplicationEventMulticaster()方法,该方法返回的ApplicationEventMulticaster类型的对象applicationEventMul ...