美文网首页Vue单页应用程序员
Vue异步插件----基于Vue和PHP打造前后端分离的通用管理

Vue异步插件----基于Vue和PHP打造前后端分离的通用管理

作者: 天渡云 | 来源:发表于2018-04-01 21:33 被阅读96次

    按照上篇的介绍,我们来具体实现这个插件。
    这个插件的功能是这样:

    • 提供统一的远程访问接口
    • 提供钩子(拦截器)实现链式流水线,大致是个切片

    首先,先定义插件的框架

    import $http from 'axios';
    import Qs from 'qs';
    
    /**
     * 提供远程访问
     *
     */
    class Http {
      /**
       * @type {Vue} 保存传进来的全局Vue对象
       */
      static vue;
    
      /**
       * 插件安装函数
       */
      static install(Vue) {
        this.vue = Vue;
    
        // this.vue.prototype.$httpGet
        // this.vue.prototype.$HttpPost
    
        // this.vue.prototype.$addReceiver
    
        // this.vue.prototype.$removeReceiver
      }
    
      /**
       * 钩子格式定义
       * @typedef Receiver
       * @type {Function}
       * @param {Object} data
       */
    
      /**
       * @type {Receiver[]} 保存钩子数组
       */
      static receivers = [];
    }
    
    export default Http;
    
    

    这样,框架就搭好了。我们定义了Http类,按照Vue插件的要求实现了静态方法instal;定义了一个全局钩子数组,定义了钩子函数的接口。

    下面我们来填充。总的思路是通过Axois远程访问,在返回的Promise对象的then函数中判断。如果返回数据,则发给钩子数组一次处理;返回错误,则显示错误信息则可。
    当然,由于返回的Promise,调用者可以也必须继续使用then链处理数据。
    具体实现附后,接下来是Mock时间,请期待。

    import $http from 'axios';
    import Qs from 'qs';
    
    /**
     * 提供远程访问
     *
     */
    class Http {
      /**
       * @type {Vue} 保存传进来的全局Vue对象
       */
      static vue;
    
      /**
       * 钩子格式定义
       * @typedef Receiver
       * @type {Function}
       * @param {Object} data
       */
    
      /**
       * @type {Receiver[]} 保存钩子数组
       */
      static receivers = [];
    
      /**
       * Url装配函数格式
       * @typedef UrlMaker
       * @type {Function}
       * @param {string} url
       * @returns {string}
       */
    
      /**
       * @type {UrlMaker} 自定义Url装配函数接口,通过在全局Vue实例中自定义Url装配函数实现定制
       */
      static createUrl = url => url;
    
      /**
       * 全局错误提示
       * @param {Error} error 错误信息
       * @param {string} message 错误信息
       */
      static onError(error, message = '') {
        return this.vue.$message && this.vue.$message({
          type: 'warning',
          message: error.message || message,
        });
      }
    
      /**
       * 参数过滤,过滤没用的GET参数
       *
       * @param {string} value 原参数
       * @param {Object} filter {key, value} 有效性定义
       * @returns {Object}
       */
      static Filter = (value, filter) => {
        let realfilter = filter;
        if (filter === true) realfilter = 'id';
        if (typeof filter === 'string') realfilter = [{ key: filter, value: 'id' }];
        const fp = {};
        realfilter.forEach((v) => { fp[v.key] = value[v.value || v.key]; });
        return fp;
      }
    
      /**
       * 远程调用的核心方法
       * @returns {Promise<T>}
       */
      static HttpSend = (url, value = null, post = false) => {
        const option = {
          method: post ? 'post' : 'get',
          // url: this.createUrl(url),
          url,
        };
        if (post) {
          option.data = Qs.stringify(value);
          option.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
        } else if (value !== null) {
          option.params = JSON.parse(JSON.stringify(value));
        }
        // 开启跨域cookie
        option.withCredentials = true;
        option.paramsSerializer = params => Qs.stringify(params, { arrayFormat: 'brackets' });
        return $http(option).then((response) => {
          const data = response.data;
          // 判断返回结果信息
          if ((function isError(v) {
            if (typeof v !== 'object') return false;
            if (v.status === false) return true;
            return (v.status && Number(v.status) <= 0);
          })(data)) return Http.onError(data, '操作无效');
          return Http.onReceive(data);
        }, error => Http.onError(error, '数据获取失败'))
          .catch(error => Http.onError(error, '内部错误'));
      };
    
      /**
       * 触发钩子函数
       * @type {Function}
       * @param {Object}  data
       * @returns {Object}
       */
      static onReceive = (data) => {
        Http.receivers.forEach(receiver => receiver(data));
        return data;
      }
    
      /**
       * 插件安装函数
       */
      static install(Vue) {
        this.vue = Vue;
    
        this.createUrl = this.vue.createUrl || (url => url);
    
        this.vue.prototype.$httpGet = (url, value = null) => this.HttpSend(url, value);
        this.vue.prototype.$HttpPost = (url, value = null) => this.HttpSend(url, value, true);
    
        this.vue.prototype.$addReceiver = receiver => this.receivers.push(receiver);
    
        this.vue.prototype.$removeReceiver = id => this.receivers.splice(id, 1);
      }
    }
    
    export default Http;
    
    

    相关文章

      网友评论

        本文标题:Vue异步插件----基于Vue和PHP打造前后端分离的通用管理

        本文链接:https://www.haomeiwen.com/subject/lawacftx.html