简单的Element UI前端框架-封装axios

接着前一篇内容:https://blog.csdn.net/wwyywwsaber/article/details/123925017

要点:

  • 统一url配置
  • 统一api请求
  • request拦截器
  • response拦截器
  • 将axios封装成vue插件使用

文件结构:

在src目录下,新建一个http文件夹,用来存放http交互api代码

  • config.js:axios默认配置,包含基础路径等信息
  • axios.js:二次封装axios模块,包含拦截器等信息
  • api.js:请求接口汇总模块,聚合所有模块API
  • index.js:将axios封装成插件,按插件方式引入
  • modules:用户管理、菜单管理等子模块API  

 简单的Element UI前端框架-封装axios_第1张图片

 

由于需要用到cookie,安装js-cookie依赖

cnpm install js-cookie

将src/components/HelloWorld.vue改为home.vue

在src目录下新建utils文件夹,创建global.js文件

//global.js代码
export const baseUrl = 'http://127.0.0.1:80'

export const backupBaseUrl = 'http://localhost:8002'

export default{
  baseUrl, backupBaseUrl
}

在src/http目录下创建config.js文件

import {baseUrl} from '@/utils/global'

export default{
  method: 'get',
  baseUrl: baseUrl,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
  data: {},
  timeout: 1000,
  withCredentials: true,
  responseType: 'json'
}

 在src/http目录下创建axios.js文件

import axios from 'axios'
import config from './config'
import Cookies from 'js-Cookie'
import router from '@/router'

export default function $axios (options) {
  return new Promise((resolve, reject) => {
    const instance = axios.create({
      baseURL: config.baseUrl,
      headers: config.headers,
      timeout: config.timeout,
      withCredentials: config.withCredentials
    })
    instance.interceptors.request.use(
      config => {
        let token = Cookies.get('token')
        if (token) {
          config.headers.token = token
        } else {
          router.push('/')
        }
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )
    instance.interceptors.response.use(
      response => {
        return response.data
      },
      err => {
        return Promise.reject(err)
      }
    )
    instance(options).then(res => {
      resolve(res)
      return false
    }).catch(error => {
      reject(error)
    })
  })
}

在src/http下新建modules文件夹,创建login.js文件

import axios from '@/http/axios'

/*
 * 系统登录模块
 */

// 登录
export const login = data => {
  return axios({
    url: 'login',
    method: 'post',
    data
  })
}

// 登出
export const logout = () => {
  return axios({
    url: 'logout',
    method: 'get'
  })
}

在src/http目录下创建api.js文件

import * as login from './modules/login'
export default{
  login
}

在src/http目录下创建index.js文件

// 导入所有接口
import api from './api'

const install = Vue => {
  if (install.installed) { return }

  install.installed = true

  Object.defineProperties(Vue.prototype, {
    // 注意,此处挂载在 Vue 原型的 $api 对象上
    $api: {
      get () {
        return api
      }
    }
  })
}

export default install

打开src/main.js,把global和api挂载进去 

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import global from '@/utils/global'
import api from '@/http'
Vue.use(ElementUI)
Vue.use(api)
Vue.config.productionTip = false
Vue.prototype.global = global
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: ''
})

打开src/router/index.js文件,修改初始定向路径

import Vue from 'vue'
import Router from 'vue-router'
import login from '@/components/login'
import home from '@/components/home'
Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'login',
      component: login
    },
    {
      path: '/home',
      name: 'home',
      component: home
    }

  ]
})

在src/compoments路径下新建login.vue




 修改src/mock/mock.js文件,模拟token数据

import Mock from 'mockjs'
Mock.mock('http://127.0.0.1:80/login', {
  'token': '1234567890'
})
Mock.mock('http://localhost:8080/user', {
  'name': '@name',
  'email': '@email',
  'age|1-10': 5
})
Mock.mock('http://localhost:8080/menu', {
  'id': '@increment',
  'name': 'menu',
  'order|1-20': 5
})

简单的Element UI前端框架-封装axios_第2张图片 

 封装mock

在src/mock目录下创建index.js

import Mock from 'mockjs'
import { baseUrl } from '@/utils/global'
import * as login from './modules/login'

// 1. 开启/关闭[所有模块]拦截, 通过调[openMock参数]设置.
// 2. 开启/关闭[业务模块]拦截, 通过调用fnCreate方法[isOpen参数]设置.
// 3. 开启/关闭[业务模块中某个请求]拦截, 通过函数返回对象中的[isOpen属性]设置.
let openMock = true
// let openMock = false
fnCreate(login, openMock)

/**
 * 创建mock模拟数据
 * @param {*} mod 模块
 * @param {*} isOpen 是否开启?
 */
function fnCreate (mod, isOpen = true) {
  if (isOpen) {
    for (var key in mod) {
      ((res) => {
        if (res.isOpen !== false) {
          let url = baseUrl
          if (!url.endsWith('/')) {
            url = url + '/'
          }
          url = url + res.url
          Mock.mock(new RegExp(url), res.type, (opts) => {
            opts['data'] = opts.body ? JSON.parse(opts.body) : null
            delete opts.body
            console.log('\n')
            console.log('%cmock拦截, 请求: ', 'color:blue', opts)
            console.log('%cmock拦截, 响应: ', 'color:blue', res.data)
            return res.data
          })
        }
      })(mod[key]() || {})
    }
  }
}

在src/mock目录新建modules文件夹,创建login.js

/*
 * 系统登录模块
 */

// 登录接口
export function login () {
  const loginData = {
    'code': 200,
    'msg': null,
    'data': {
      'id': null,
      'userId': 1,
      'token': '77ae89be36504adfb5c09ef71409ea0e',
      'expireTime': '2018-09-01T16:24:50.473+0000',
      'createBy': null,
      'createTime': null,
      'lastUpdateBy': null,
      'lastUpdateTime': '2018-09-01T04:24:50.473+0000'
    }
  }
  return {
    url: 'login',
    type: 'post',
    data: loginData
  }
}
// 登出接口
export function logout () {
  const logoutData = {
    'code': 200,
    'msg': null,
    'data': {
    }
  }
  return {
    url: 'logout',
    type: 'get',
    data: logoutData
  }
}

更改login.vue中模拟数据的装载

简单的Element UI前端框架-封装axios_第3张图片 

 至此,axios和mock封装基本完毕

你可能感兴趣的:(一个简单的前后台分离系统,elementui,vue.js)