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 相关文章推荐
在IE下:float属性会影响offsetTop的取值
Dec 22 Javascript
[原创]站长必须要知道的javascript广告代码
May 30 Javascript
jquery网页回到顶部效果(图标渐隐,自写)
Jun 16 Javascript
深入分析原生JavaScript事件
Dec 29 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
Nov 07 Javascript
详解vue+vueRouter+webpack的简单实例
Jun 17 Javascript
深入理解Vue-cli搭建项目后的目录结构探秘
Jul 13 Javascript
js封装成插件的步骤方法
Sep 11 Javascript
Node.js+ELK日志规范的实现
May 23 Javascript
构建Vue大型应用的10个最佳实践(小结)
Nov 07 Javascript
ant-design-vue按需加载的坑的解决
May 14 Javascript
解决pycharm双击但是无法打开的情况
Oct 31 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
浅谈php中mysql与mysqli的区别分析
2013/06/10 PHP
JS异常处理try..catch语句的作用和实例
2014/05/05 PHP
PHP实现RTX发送消息提醒的实例代码
2017/01/03 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
2018/02/10 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
2018/12/05 PHP
PHP学习记录之常用的魔术常量详解
2019/12/12 PHP
javascript网页关键字高亮代码
2008/07/30 Javascript
js loading加载效果实现代码
2009/11/24 Javascript
基于jquery的复制网页内容到WORD的实现代码
2011/02/16 Javascript
fmt:formatDate的输出格式详解
2014/01/09 Javascript
js返回上一页并刷新的多种实现方法
2014/02/26 Javascript
jquery.idTabs 选项卡使用示例代码
2014/09/03 Javascript
下拉框select的绑定示例
2014/09/04 Javascript
网页中表单按回车就自动提交的问题的解决方案
2014/11/03 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 语法
2015/01/09 Javascript
AngularJS初始化静态模板详解
2016/01/14 Javascript
微信小程序 实战程序简易新闻的制作
2017/01/09 Javascript
原生js调用json方法总结
2018/02/22 Javascript
vue实现点击关注后及时更新列表功能
2018/06/26 Javascript
Node.js console控制台简单用法分析
2019/01/04 Javascript
微信小程序实现左滑动删除效果
2020/03/30 Javascript
JavaScript语句错误throw、try及catch实例解析
2020/08/18 Javascript
[42:32]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第二局
2016/02/27 DOTA
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
python脚本生成caffe train_list.txt的方法
2018/04/27 Python
python计算n的阶乘的方法代码
2019/10/25 Python
Python %r和%s区别代码实例解析
2020/04/03 Python
css3 伪元素和伪类选择器详解
2014/09/04 HTML / CSS
AmazeUI导航的示例代码
2020/08/14 HTML / CSS
Smashbox官网:美国知名彩妆品牌
2017/01/05 全球购物
阿玛尼意大利官网:Armani意大利
2018/10/30 全球购物
群众路线教育实践活动自我剖析思想汇报
2014/10/04 职场文书
消防验收申请报告
2015/05/15 职场文书
初中毕业感言300字
2015/07/31 职场文书
2016年度员工工作表现评语
2015/12/02 职场文书
docker compose 部署 golang 的 Athens 私有代理问题
2022/04/28 Servers