Vue-resource

在实际开发 SPA 应用时,一般和后端都会采用异步接口进行数据交互。传统情况下,我 们常用 jQuery 的 $.ajax() 方法来做异步请求。但 Vue.js 并不依赖于 jQuery,我们也并不需 要为了异步请求这个功能就额外引用 jQuery。所以这里就和大家介绍下 Vue.js 的插件 Vue- resouce,它同样对异步请求进行了封装,方便我们同服务端进行数据的交互。

安装
npm install vue-resource
//main.js
import VueResource from "vue-resource"
Vue.use(VueResource)
使用方式

安装好 Vue-resource 之后,在 Vue 组件中,我们就可以通过 this.$http 或者使用全局 变量 Vue.http 发起异步请求,例如:

VueResource组件:

<template>
  <div>
    <h2>vue-resource test</h2>
    <button type="button" @click="test">点击发送请求</button>
    <p>{{msg}}</p>
  </div>
</template>

<script>
export default {
  name: 'ResourceTest',
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    test() {
      //这段代码需要运行在服务器环境中
      this.$http
          .get("/hello")
          .then(function(rep){//成功的回调函数
              this.msg = rep.data
          }, function(rep){//失败的回调函数
              alert(rep.data)
          })
    }
  }
}
</script>

app.vue

<template>
  <div id="app">
    <!-- <img src="./assets/logo.png"> -->
    <router-link to="/">首页</router-link>
    <router-link to="/test">test</router-link>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

路由:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import ResourceTest from '@/components/ResourceTest';

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/test',
      name: 'ResourceTest',
      component: ResourceTest
    }
  ]
})

配置代理,在config/index.js中:

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {//代理
      '/hello': {
        target: 'http://localhost',//代理到本地80端口
        changeOrigin: true,
        pathRewrite: {
          '^/hello': '/hello'
        }
      }
    },
	...
}

启动后端服务,go语言:

import (
	"fmt"
	"net/http"
)

/*
 */
func main() {
	server := &http.Server{
		Addr: "0.0.0.0:80",
	}
	http.HandleFunc("/hello", hello)
	server.ListenAndServe()
}

func hello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "hello world")
}

启动前端服务:
在这里插入图片描述
点击按钮:
在这里插入图片描述

$http的api方法和选项参数

this.$http 可以直接当做函数来调用,我们以下面这个例子来对其选项进行说明:

this.$http({
  url: '/api/list',//url访问路径
  method: '',//HTTP请求方法,例如GET,POST,PUT,DELETE等
  body: {},//request中的body数据,值可以为对象,String类型,也可以是FormData对象
  params: {},//get方法时url上的参数,例如/api/list?page=1
  headers: {}, //可以设置request的header属性
  timeout: 1500,//请求超时时长,单位为毫秒,如果设置为0的话则没有超时时长
  before: function(request){},//请求发出前调用的函数,可以在此对request进行修改
  progress: function(event){},//上传图片、音频等文件时的进度,event对象会包含上传文件的总大小和已上传大小,通常可以用来作为进度条效果
  credentials: boolean,//默认情况下,跨域请求不提供凭据 (cookie、HTTP 认证及客户端 SSL 证明等 )。该选项可以通过将 XMLHttpRequest 的 withCredentials 属性设置为 true, 即可以指定某个请求强制发送凭据。如果服务器接收带凭据的请求,会用 Access-Control-Allow- Credentials: trueHTTP 头部来响应
  emulateHTTP: boolean,// 设置为true后,PUT/PATCH/DELETE请求将被修改成 POST 请求,并设置 header 属性 X-HTTP-Method-Override。常用于服务端不支持 REST 写法时
  emulateJSON: boolean //设置为 true 后,会把 request body 以 application/ x-www-form-urlencoded 的形式发送,相当于 form 表单提交。此时 http 中的 header 的 content- type 即为 application/x-www-form-urlencoded。常用于服务器端未使用 application/json 编码时
 })

此外,this.$http 还可以直接调用 api 方法,相当于提供了一些快捷方式,例如:

get(url, [options])
head(url, [options]) 
delete(url, [options]) 
jsonp(url, [options]) 
post(url, [body], [options]) 
put(url, [body], [options]) 
patch(url, [body], [options])

以上方法均可以采用 this.$http.get(url, options)Vue.http.get(url, options) 这样类 似的形式进行调用。

在发起异步请求后,我们可以采用 this.$http.get(...).then() 的方式处理返回值。.then() 接受一个 response 的参数,具体的属性和方法如下。

url: response 的原始 url。
body :response 的 body 数据,可以为 Object,Blob,或者 String 类型。
headers :response 的 Headers 对象。
ok: 布尔值,当 HTTP 状态码在 200299 之间时为 truestatus: response 的 HTTP 状态码。
statusText: response 的 HTTP 状态描述。

//另外还包含以下三种 api 方法。
text(): Promise 类型,把 response body 解析成字符串。
json(): Promise 类型,把 response body 解析成 json 对象。
blob(): Promise 类型,把 response body 解析成 blob 对象,即二进制文件,多用于图片、音视频等文件处理。

拦截器

拦截器主要作用于给请求添加全局功能,例如身份验证、错误处理等,在请求发送给服 务器之前或服务器返回时对 request/response 进行拦截修改,完成业务逻辑后再传递给下一 步骤。Vue-resource 也提供了拦截器的具体实现方式,例如:

Vue.http.interceptors.push(function(request, next) {   
	// 修改请求
  	request.method = 'POST';
 	// 继续进入下一个拦截器
  	next(); 
});

也可以对返回的 response 进行处理:

Vue.http.interceptors.push(function(request, next){   
	request.method = 'POST';
  	next(function(response) {
   		// 修改response
   		response.body = '...';   
	});
});

或者直接拦截返回 response,并不向后端发送请求:

Vue.http.interceptors.push(function(request, next) {
  // body 可自己定义,request.respondWith 会将其封装成 response,并赋值到 response.body 上   
  	next(request.respondWith(body, {
   	status: 403,
   	statusText: 'Not Allowed
  }));
});

$resource用法

Vue-resource 提供了一种与 RESTful API 风格所匹配的写法,通过全局变量 Vue. resource 或者组件实例中的 this.$resource 对某个符合 RESTful 格式的 url 进行封装,使得 开发者能够直接使用增删改查等基础操作,而不用自己再额外编写接口。

我们先大致说明下 RESTful API :这是一种设计风格而不是标准,只是提供了一组设 计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可 以更简洁,更有层次,更易于实现缓存等机制。在这种风格中,每个 url 路径代表一种资源
(resource),所以路径中不推荐有动词,只能有名词,而且所用的名词往往与数据库的表格 名对应,且一般采取复数的形式命名。而对于资源的具体操作类型,则由 HTTP 动词表示, 即 GET/POST/PUT/PATCH/DELETE 等。

我们以产品 products 为例,设计出的 api 即为。
GET /api/products, :获取所有产品列表。
POST /api/products :新建一个产品。
GET /api/products/:id :获取某个指定产品信息。
PUT /api/products/:id :更新某个指定产品信息。
DELETE /api/products/:id :删除某个指定产品。
GET /api/products/:id/items :获取某个指定产品下的 items 信息列表。 在需要对信息进行过滤的情况下,以 query 参数形式进行筛选,例如:

GET /api/products?limit=10&offset=10&sortBy=name

简单说明完 RESTful 后,结合 this.$resource,我们可以使用与后端接口对接:

var products = this.$resource('/api/products{/id}');
// 相当于发起异步GET请求, 访问/api/products/1接口,获取指定产品信息 
products
  .get({ id : 1})
  .then(function(rep) {
   this.$set('products', rep.json());
 })
 
// POST /api/products 参数为 data,新建一个产品
products
  .save({}, data)
  .then(function(rep) {
....
 })

Vue-resource 提供了 6 个默认动作行为,分别为:

get: {method: 'GET'},
save: {method: 'POST'}, 
query: {method: 'GET'}, 
update: {method: 'PUT'}, 
remove: {method: 'DELETE'}, 
delete: {method: 'DELETE'}

除了默认行为外,Vue-resource 也允许我们自定义行为,例如:

var customActions = {
  order : { method: 'POST', url : '/api/products{/id}/orders'} };
var products = this.$resource('/api/products{/id}');
// 即调用异步接口 POST /api/products/1/orders
products
  .order({ id : 1})
  .then(function(rep) { .... })

封装Service层

在编写 SPA 应用中,我们通常会把和后端做数据交互的方法封装成一个 Service 模块, 供不同的组件进行使用。我们可以新建一个文件夹 api,将 Service 模块集中起来,并按资源 进行分类。
以上述 products 资源为例:

//  /api/products.js
const API_URL = '/api/products; 

export default {
  get(context, productId) {
   return context.$http({
   		url : API_URL + '/' + productId,
   		method : 'get'
   });
 },
  query(context, params) {   
  	return context.$http({     
  		url : API_URL,
    	params : params   
    })
 }
  .........
}

在组件中调用方式如下:

import productsSrv from './api/products.js';
var ProductDetail = Vue.component('product-detail', {   
	route : {
   		data : function(transition) {
    		productsSrv
     			.query(this, transition.to.params)
     			.then(function(rep) {
     	})    
     }
 }
});
Logo

前往低代码交流专区

更多推荐