码迷,mamicode.com
首页 > 其他好文 > 详细

ceshi

时间:2020-02-22 19:57:21      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:methods   pack   服务端   path   test   err   --   ams   content   

### Vue.js 

## 一、 axios的封装

### 1.1在src根目录 新建providers文件 ,以及添加几个主要的 文件
 |---providers
 |-----util.js  工具函数
 |-----api.js   接口地址
 |-----axios.js  封装axios的文件

 mkdir providers
 touch  util.js api.js axios.js

 ### 1.2 配置工作环境 (dev,test,build)
    安装:
    yarn add cross-env -D

    在package.json里配置:
    "scripts": {
        "test":"cross-env scene=test webpack --config webpack.config.js",
        "dev":"cross-env scene=dev webpack-dev-server --config webpack.config.js",
        "build":"cross-env scene=prod webpack --config webpack.config.js"
        },

    在配置文件webpack.config.js通过内置插件DefinePlugin配置
    var webpack = require(‘webpack‘);

        plugins.push(new webpack.DefinePlugin({
            ‘sceneParam‘: JSON.stringify(process.env.scene),
            ‘laney‘:JSON.stringify(‘laney‘),
            ‘test‘:‘"kkkkk"‘
        })); 


重新启动就可以在项目中直接获取到 sceneParam 参数

### 1.3 添加登陆页面  pages/login.vue

    参照:Element ui Form表单
    https://element.eleme.cn/#/zh-CN/component/form

    校验利用策略模式, 和es5里的form表单验证思想一致
    校验成功后, 调取登陆接口

    submitLogin(){
            var {pass,username} = this.ruleForm
            axios({
                method:‘post‘,
                url:‘http://localhost:8081/api/login‘,
                data:{
                    name:username,
                    password:pass
                }
            }).then((res)=>{
                
                if(res.data.statusCode==200) {
                     alert(res.data.data);
                     localStorage.setItem(‘token‘,res.data.token); //用户访问页面的钥匙
                     
                     this.$router.push({
                         path:‘/home‘
                     });
                } else {
                     alert(res.data.data);
                }
               
            });
               
        }

### 1.3 在home.vue页面调取相关接口 ,如何处理接口的多级回调
   pages/home.vue

export default {
    data(){
        return {
            name:‘laney‘,
            params:this.$route.query,
            infoData:{}
        }
    },
    methods:{
        getInfoList(){
            var token = localStorage.getItem(‘token‘);
            var test = {name:‘laney‘,age:‘20‘}
            var mn = Qs.stringify(test);
            // this.$axios.post(‘http://localhost:8081/api/info‘,mn).then((res)=>{
            //     console.log(‘test kkkk-----------‘);
            // })
             this.$axios({
                method:‘post‘,
                url:‘http://localhost:8081/api/info‘,
                data:mn,
                headers:{
                    token:token
                }
            }).then((res)=>{
                if(res.data.statusCode==200) {     
                     this.infoData = res.data.result;
                     var tag = res.data.tag;
                     return this.$axios({
                            method:‘post‘,
                            url:‘http://localhost:8081/api/msg‘
                        })
                } else {
                     alert(res.data.result);
                }
            }).then((res)=>{
                console.log(res.data.result)
            });
        }
    },
    mounted(){
        this.getInfoList();
    }
}
</script>

### 1.4 配置api

export default {
    basic:{
        login:‘/api/login‘,
        info:‘/api/info‘,
        msg:‘/api/msg‘,
        hello:‘/api/hello‘

    }
}

### 1.5 在入口文件main.js进行引入
    import axios from ‘./providers/axios.js‘;
    import api from ‘./providers/api.js‘;

    //定义全局变量$axios
    Vue.prototype.$axios = axios;
    Vue.prototype.$api = api;

### 1.6 配置axios

    yarn add axios -D , 已安装的可以忽略
    引入axios 
    import axios from ‘axios‘;
    
    导出的结构是:
    export default {
      post, //方法名
      get,
      pull
    }
    封装的目的:
        1.需要把一些 api 的base路径配置好,以免多次重复写入
        2.项目可能传递给接口的 数据 有json 和 formData 都需要考虑
        3.对登陆后可能权限的 token需要获取 统一设置
        4.对接口异常的情况需要统一处理

#### 1.6.1 第一种方式, 利用拦截器配置headers

    后面讲


#### 1.6.2 第二种方式, 不利用拦截器配置headers
整体思路是在传参的时候, 可以多加一个参数form(true,false), true代表需要formData , false或者不选代表json
参考: axios2.js

var typearr= {
  ‘json‘:‘application/json;charset=UTF-8‘,
  ‘form‘:‘application/x-www-form-urlencoded‘
};
  post (url, params) {
      var isForm = params.form;
      if(params.form)  {
        delete params.form;
      }
      if(isForm) {
        params = Qs.stringify(params);
      }

    return new Promise((resolve,reject) => {
       return axios.post(url,params, {
          headers: {
            ‘X-API-TOKEN‘:localStorage.getItem(‘token‘),
            ‘Content-Type‘: isForm ? typearr[‘form‘] : typearr[‘json‘],
            ‘test‘:‘ppp‘
          }
      })
        .then(response => {
          if(response.status==200){
             resolve(response.data);
          } 
          //这里不需要异常提示了, 已经在拦截器设置
          // else {
          //   Message({
          //     message: response.errorMsg,
          //     type: ‘warning‘
          //   });
          // }
        })
        .catch(err => {
          reject(err)
        })
      })
  },


### 1.7在页面中使用 
 以news.vue为例

 <script>
export default {
    data(){
        return {
            infoData:{}
        }
    },
    methods:{
        getInfoList2(){
            var res = this.$axios.post(this.$api.basic.info,{
                kind:‘school‘,
                form:true
            }).then((res)=>{  
                console.log(res);
            });
        },
        
        getInfoList(){
          this.$axios.post(this.$api.basic.info,{
              kind:‘school‘
          },‘form‘).then((res)=>{
              this.infoData = res.result;
                if(res.tag==1){
                    return  this.$axios.post(this.$api.basic.msg,{
                        tag:res.tag
                    })
                }
          }).then((res)=>{
              if(res.kind==2){
                    return  this.$axios.post(this.$api.basic.hello,{
                        id:res.kind
                    })
              }
          }).then((res)=>{
              console.log(res.result);
          })
  
        }
    },
    mounted(){
        this.getInfoList2();
        // this.getInfoList();
        
    }
}
</script>


### 1.8 拦截器的处理以及异常处理

var formData = new FormData();
formData.append(‘name‘,‘song‘);
formData.get(‘name‘);

//http request 拦截器  你给服务端 的数据 
axios.interceptors.request.use(
  config => {   
    config.headers.common = {
      ‘X-API-TOKEN‘: localStorage.getItem(‘token‘),
      ‘version‘: ‘1.0‘,
      ‘Content-Type‘: ‘application/json;charset=UTF-8‘
    }
    console.log(‘begin‘);
    if (config.data.form) {
        //转化成formData格式
        // transformRequest只能用在 PUT, POST, PATCH 这几个请求方法
        config.transformRequest=[function (data) {
            //方式一
            data.name=‘laney‘;
            delete data.form;
            var ret = ‘‘;
            for (let it in data) {
              ret += it+‘=‘ +data[it] + ‘&‘;
            }
            return ret.substring(0,ret.length-1);

            //方式二:
            // var test2 = Qs.stringify(data);
            // return test2;
          }]
        }

    return config;
  },
  error => {
    return Promise.reject(err);
  }
);

//响应拦截器即异常处理 -  -- 服务给我们的数据
axios.interceptors.response.use(response => {
    
    if (response.status === 200) {
        return Promise.resolve(response);
    } else {
        return Promise.reject(response);
    }
    // return response
}, err => {
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
            console.log(‘错误请求‘)
          break;
        case 401:
            console.log(‘未授权,请重新登录‘)
          break;
        case 403:
          console.log(‘拒绝访问‘)
          break;
        case 404:
          console.log(‘请求错误,未找到该资源‘)
          break;
        case 405:
          console.log(‘请求方法未允许‘)
          break;
        case 408:
          console.log(‘请求超时‘)
          break;
        case 500:
          console.log(‘服务器端出错‘)
          break;
        case 501:
          console.log(‘网络未实现‘)
          break;
        case 502:
          console.log(‘网络错误‘)
          break;
        case 503:
          console.log(‘服务不可用‘)
          break;
        case 504:
          console.log(‘网络超时‘)
          break;
        case 505:
          console.log(‘http版本不支持该请求‘)
          break;
        default:
          console.log(`连接错误${err.response.status}`)
      }
    } else {
      console.log(‘连接到服务器失败‘)
    }
    return Promise.resolve(err.response)
})


然后开始封装函数

export default {
  /**
   * 封装post方法
   * @param url
   * @param data
   * @returns {Promise}
   * 
   */
// 方式一: 包装一个 new Promise
  // post (url, params) {
  //   return new Promise((resolve,reject) => {
  //      return axios.post(url,params)
  //       .then(response => {
  //         if(response.status==200){
  //            resolve(response.data);
  //         } else {
  //           alert(response.errorMsg);
  //         }
  //       })
  //       .catch(err => {
  //         reject(err)
  //       })
  //     })
  // },
// 方式二: 包装一个 直接利用axios自身是一个Promise对象的思想封装
  // post (url, params) {
  //      return axios.post(url,params)
  //       .then(response => {
  //         if(response.status==200){
  //           return Promise.resolve(response.data); 
  //           //注意必须要有return,相当于new Promise里的resolve,告诉接口已经获取数据
  //         } else {
  //           alert(response.errorMsg);
  //         }
  //       })
  //       .catch(err => {
  //         reject(err)
  //       })
  // },

//方式三
// 注意: axios在配置headers头的时候, 不要和上面的 拦截器重复配置
  post (url, params) {
      var isForm = params.form;
      if(params.form)  {
        delete params.form;
      }
      if(isForm) {
        params = Qs.stringify(params);
      }
      return axios({
        method: ‘post‘,
        url:url,
        data: params
      }).then((response) => {
        
        if(response.status==200){
          return Promise.resolve(response.data)  
        } else {
          <!-- 如果设置了拦截器, 这里不需要做异常处理 -->
          alert(response.errorMsg);
        }
        },(e) => {
          return Promise.reject(e)
        }) 
        // 或者catch捕获异常
        .catch(function (error) {
          
        })
  },

//方式四:
// async post (url, params,contype) {
//     if(contype==‘form‘){
//       params = Qs.stringify(params);
//     }
//     var res = await axios({
//         method: ‘post‘,
//         url:url,
//         data: params
//     });
//   return res.data;

// },

  get(url,params={}){
    return new Promise((resolve,reject) => {
      axios.get(url,{
        params:params
      })
      .then(response => {
        resolve(response.data);
      })
      .catch(err => {
        reject(err)
      })
    })
  },
}


### 1.9 异常消息提示
在axios.js里 添加
import { Message} from ‘element-ui‘;

然后直接使用
Message({
      message: ‘提示信息‘,
      type: ‘warning‘
    });


## 一、 addRoutes的封装

//需要登陆后确认权限才能看到的路由
    var asyncUser = [
        {
            path:‘/finance‘,
            component:Finance,
            meta: {
                title: ‘财务信息‘,
                roles: [‘admin‘]
              }
  },
  {
            path:‘/news‘,
            component:News,
            meta: {
                title: ‘新闻中心‘,
                roles: [‘admin‘,‘guest‘]
              }
        }
    ];

       // 导航守卫 -- 全局前置守卫
        routerAll.beforeEach((to,from,next)=>{
      //这里可以获取登陆后的权限, 如果是admin
      asyncUser = asyncUser.filter((item,index)=>{
        return item.meta.roles.includes(‘guest‘)
      })
              //将新路由添加到路由中, 如果不加组件component不能正确渲染
            routerAll.addRoutes(asyncUser); 
            //为了正确渲染导航,将对应的新的路由添加到routerAll中
            routerAll.options.routes = [...routes,...asyncUser];
            next();
        })


    




ceshi

标签:methods   pack   服务端   path   test   err   --   ams   content   

原文地址:https://www.cnblogs.com/laneyfu/p/12346797.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!