Vue使用Proxy监听所有接口状态的方法实现


Posted in Javascript onJune 07, 2019

在开发项目过程中几乎所有接口都需要知道它的返回状态,比如失败或者成功,在移动端通常后台会返回结果,而我们只需要一个弹窗来弹出来结果就可以了。但是这个弹窗如果在整个项目里需要手动去每一个都定义,那是非常庞大的代码量,而且维护起来非常的麻烦。通常做法就是绑定在原型上一个公共方法,比如this.message('后台返回接口信息')。 这样看似省力了很多其实还是很麻烦。 如果使用了proxy做一个全局代理,那么就完全不一样了。不管任何一个api都会将状态传递个这个代理中心,并且由代理中心直接反应结果。

Vue使用Proxy监听所有接口状态的方法实现

import Vue from 'vue'
import {ToastPlugin} from 'vux'
import api from './api/api'
//引入封装好的api模块,和使用的toast弹出窗,弹窗可以选择任何框架的看起来比较好看的弹窗组件
Vue.use(ToastPlugin);
//toast初始化
let vm = new Vue();
//创建实例,是因为toast弹窗依赖它所以这里要创建个实例,去调用弹窗用
Vue.prototype.dilog = function (value) {
 vm.$vux.toast.show({
 text: value || "业务处理成功",
 type: 'text',
 width: "5rem",
 position: 'middle'
 });
};
//陷阱,只要接口状态改变就会调用此方法
var interceptor = {
 set: function (recObj, key, value) {
 vm.dilog(value);
 //弹出层,value就是api返回的状态值
 return this
 }
};
//创建代理以进行侦听
var proxyEngineer = new Proxy(api, interceptor);
Vue.prototype.api = proxyEngineer;
//将api替换为新的实例

之所以这样做,是因为创建好的封装好的api文件里,不应该在去引入一个vue实例了,如果不用代理,直接在api文件里引入vue那将是巨大的消耗。

class API {
 constructor(){
 this.massages = "业务处理成功!";
 //定义信息状态属性
 //当前接口错误提示
 this.code='000000'||'999999'
 }

 post(params, callback, dailog, errcallback = function () { //错误信息回调}) {
 //dailog 是是否需要在初始化弹窗,比如一个列表通常不需要加载完了弹出一个加载成功,或者获取数据成功什么的。Boolean,通常只需要在点击某事件时候使用,或者是初///始化数据报错使用 
 //this.code 代表状态码
 let config={};
 config.data = params.data||{};
 var url = `${base}${params.url}.do`;
 var dailog = dailog;
 //封装了axios的post方法
 return axios.post(url, config.data, config, dailog).then(res => {
  let rst = res.data;
  if (rst.code === '000000' || rst.code === '999999') {
  callback&&callback(rst.result||{});
  if (dailog) {
  //根据dailog 值来判断需不需要弹窗
   this.massages = rst.message;
  }
  }else{
  errcallback && errcallback();
  this.massages=rst.message;
  //监听massages的变化
  }
  //这里如果返回this返回的是代理对象的this
  return res
 }).catch(e => {
  console.log(e)
 })
 }

}
const api = new API();

export default api
//代码核心地方其实就是在类上定义了信息字段,通过massages值变化来反馈信息

Vue使用Proxy监听所有接口状态的方法实现

我所使用的toast效果。

this.api.post(params, res => {
  //你需要执行的逻辑
 // 再也不需要写什么
  //this.$msg(res.value) 这类的代码,代理已经都帮你处理完了
 })

这就是我在实际中用到的代理,这个方法不管在多页面还是单页面都适用。当然代码有些粗糙,也没做过多限制,只是说了下思想。以防自己忘记。

顺带说下代理这个特性这里就把《Understanding ECMAScript 6》这本书的内容拿来用了,并稍微添加一些自己的理解。只做记录。

代理与反射是什么?

通过调用 new Proxy() ,你可以创建一个代理用来替代另一个对象(被称为目标),这个代 理对目标对象进行了虚拟,因此该代理与该目标对象表面上可以被当作同一个对象来对待。 代理允许你拦截在目标对象上的底层操作,而这原本是 JS 引擎的内部能力。拦截行为使用了 一个能够响应特定操作的函数(被称为陷阱)。 拦截器的概念比较重要。 Reflect 拦截器有一些反射接口,

Vue使用Proxy监听所有接口状态的方法实现

拦截的作用其实就是重写内置对象的特定方法。

创建一个简单的代理

let target = {};
let proxy = new Proxy(target, {});
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
console.log(target.name); // "proxy"
target.name = "target";
console.log(proxy.name); // "target"
console.log(target.name); // "target"
proxy拦截代理了target

我主要使用到的点

let target = {
name: "target"
};
let proxy = new Proxy(target, {
set(trapTarget, key, value, receiver) {
// 忽略已有属性,避免影响它们
if (!trapTarget.hasOwnProperty(key)) {
if (isNaN(value)) {
throw new TypeError("Property must be a number.");
}
}
// 添加属性
return Reflect.set(trapTarget, key, value, receiver);
}
});
// 添加一个新属性
proxy.count = 1;
console.log(proxy.count); // 1
console.log(target.count); // 1
// 你可以为 name 赋一个非数值类型的值,因为该属性已经存在
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
console.log(target.name); // "proxy"
// 抛出错误
proxy.anotherName = "proxy";

另外vue3.0 的响应式也是使用的代理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery validator 插件增加日期比较方法
Feb 21 Javascript
js注意img图片的onerror事件的分析
Jan 01 Javascript
JavaScript的arguments对象应用示例
Sep 15 Javascript
javascript面向对象之共享成员属性与方法及prototype关键字用法
Jan 13 Javascript
JavaScript中的toDateString()方法使用详解
Jun 12 Javascript
JS获取下拉框显示值和判断单选按钮的方法
Jul 09 Javascript
jquery append 动态添加的元素事件on 不起作用的解决方案
Jul 30 Javascript
jquery中表单 多选框的一种巧妙写法
Sep 06 Javascript
前端设计师们最常用的JS代码汇总
Sep 25 Javascript
bootstrap IE8 兼容性处理
Mar 22 Javascript
React如何利用相对于根目录进行引用组件详解
Oct 09 Javascript
swiper自定义分页器使用方法详解
Sep 14 Javascript
你了解vue3.0响应式数据怎么实现吗
Jun 07 #Javascript
ES6小技巧之代替lodash
Jun 07 #Javascript
vue+element 模态框表格形式的可编辑表单实现
Jun 07 #Javascript
vue-cli3项目展示本地Markdown文件的方法
Jun 07 #Javascript
Element实现表格分页数据选择+全选所有完善批量操作
Jun 07 #Javascript
详解vue项目中实现图片裁剪功能
Jun 07 #Javascript
sortable+element 实现表格行拖拽的方法示例
Jun 07 #Javascript
You might like
根德YB400的电路分析
2021/03/02 无线电
php获取ip的三个属性区别介绍(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)
2012/09/23 PHP
PHP得到mssql的存储过程的输出参数功能实现
2012/11/23 PHP
PHP与MongoDB简介|安全|M+PHP应用实例详解
2013/06/17 PHP
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
smarty模板中使用get、post、request、cookies、session变量的方法
2014/04/24 PHP
laravel5.4生成验证码的实例讲解
2017/08/05 PHP
极酷的javascirpt,让你随意编辑任何网页
2007/02/25 Javascript
js同时按下两个方向键
2007/12/01 Javascript
学习ExtJS Column布局
2009/10/08 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
jQuery右侧选项卡焦点图片轮播特效代码分享
2015/09/05 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
Js的Array数组对象详解
2016/02/22 Javascript
java中String类型变量的赋值问题介绍
2016/03/23 Javascript
js文件中直接alert()中文出来的是乱码的解决方法
2016/11/01 Javascript
jquery实现表单获取短信验证码代码
2017/03/13 Javascript
Express下采用bcryptjs进行密码加密的方法
2018/02/07 Javascript
浅谈webpack4.x 入门(一篇足矣)
2018/09/05 Javascript
nodejs 使用 js 模块的方法实例详解
2018/12/04 NodeJs
[46:47]2014 DOTA2国际邀请赛中国区预选赛 DT VS HGT
2014/05/22 DOTA
python正则表达式中的括号匹配问题
2014/12/14 Python
使用Python简单的实现树莓派的WEB控制
2016/02/18 Python
基于循环神经网络(RNN)的古诗生成器
2018/03/26 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
django2.2 和 PyMySQL版本兼容问题
2020/02/17 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
2020/03/24 Python
一文详述 Python 中的 property 语法
2020/09/01 Python
浅谈HTML5 & CSS3的新交互特性
2016/07/19 HTML / CSS
美国生鲜及杂货电商:FreshDirect
2018/01/29 全球购物
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
公司总经理岗位职责
2014/03/15 职场文书
竞选班干部演讲稿500字
2014/08/20 职场文书
主题班会开场白
2015/06/01 职场文书
小学英语教学反思范文
2016/02/15 职场文书
《亲亲我的妈妈》观后感(3篇)
2019/09/26 职场文书