关于vue前端离线(无接口)场景下开发或展示

        前几年有一个项目需要在还没有开发接口的情况下,需要前端独立开发,review,或者给客户展示demo,都需要模拟有接口可进行操作的环境,可以使用mock来完成,考虑换种方式完成就自己构建json模拟数据,模拟api.js,这里对mock的方式不做阐述,以登录功能为例说明:

       具体部署如下:

一、模拟接口返回数据

需要用到vuex,安装:

npm i vuex -S or yarn add vuex -S

二、模拟api接口并构造返回数据

1、模拟api,首先需要用到axios,安装axios

npm i axios -S or yarn add axios -S

2、需要使用vuex构造存储json模拟接口返回的数据,安装vuex

npm i vuex -S or yarn add vuex -S

3、构造json模拟数据

在src\store下新建文件xxx.js

代码如下:

const user = {
  state: {
    loginCacheData: { "msg": "操作成功", "code": 200, "token": "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjJjYjYyNzkzLTQ1Y2UtNGY3YS04ZmNjLTE4M2E4YWZkOTE3ZiJ9.kD1ScvEHuDJVTMl1KPUf3coYaN8s42T22bPE1dLXxzZMb7zZr0IkooivAk11aEQYb5q0ExW6n066Tf6AzU7vbQ" },

    getInfoCacheData: { "msg": "操作成功", "code": 200, "permissions": ["*:*:*"], "roles": ["admin"], "user": { "searchValue": null, "createBy": "admin", "createTime": "2018-03-16 11:33:00", "updateBy": "ry", "updateTime": "2020-11-18 11:29:03", "remark": "管理员", "params": {}, "userId": 1, "deptId": 100, "userName": "admin", "nickName": "管理系统", "email": "[email protected]", "phonenumber": "15888888888", "sex": "男", "avatar": "/profile/avatar/2021/02/26/0a499c87-6391-4021-9452-ab0e2e8aaf6a.jpeg", "salt": null, "status": "0", "delFlag": "0", "loginIp": "127.0.0.1", "loginDate": "2018-03-16T11:33:00.000+0800", "dept": { "searchValue": null, "createBy": null, "createTime": null, "updateBy": null, "updateTime": null, "remark": null, "params": {}, "deptId": 100, "parentId": null, "ancestors": null, "deptName": null, "orderNum": null, "leader": null, "phone": null, "email": null, "status": null, "delFlag": null, "parentName": null, "deptType": null, "children": [], "professionId": null }, "roles": [], "roleIds": null, "postIds": null, "idCardNo": "370521197810182817", "idCardFront": "http://xxx/1605670142299.jpg", "idCardBack": "http://xxx/1605670146726.jpg", "userGroup": "1", "deptName": null, "pName": null, "cTime": null, "aStatus": null, "professionId": null, "dateTime": null, "dateTimeEnd": null, "code": null, "classId": null, "className": null, "authentication": null, "address": null, "admin": true } },

  },
}

三、模拟数据接口调用

src\api下新建cacheApi文件夹,新建login.js文件,代码如下:

import request from '@/utils/request'
import store from '@/store'
// 登录方法
export function login(username, password, code, uuid) {
  const data = {
    username,
    password,
    code,
    uuid
  }
  return new Promise(resolve => {
    const response=store.state.user.loginCacheData
    resolve(response)
  })
}

/utils/request.js是对axios进行了封装,加入了拦截器,关于token处理相关的依赖,根据自己项目情况开发,每个项目里应该都有,不做详解了,代码如下:

import axios from 'axios'
import { Notification, MessageBox, Message ,Loading} from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000
})

let loading;
// request拦截器
service.interceptors.request.use(config => {
  loading = Loading.service({
    lock: true,
    text: '努力加载中...',
    spinner: 'el-icon-loading',
    background: 'rgba(0, 0, 0, 0.7)'
  });



  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  if (getToken() && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
  return config
}, error => {
  console.log(error)
  Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(res => {

  loading.close();



  // loading.close();

  // 未设置状态码则默认成功状态
  const code = res.data.code || 200;
  // 获取错误信息
  const message = errorCode[code] || res.data.msg || errorCode['default']
  if (code === 401) {
    MessageBox.confirm(
      '登录状态已过期,您可以继续留在该页面,或者重新登录',
      '系统提示',
      {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      store.dispatch('LogOut').then(() => {
        location.reload() // 为了重新实例化vue-router对象 避免bug
      })
    })
  } else if (code === 500) {
    Message({
      message: message,
      type: 'error'
    })
    return Promise.reject(new Error(message))
  } else if (code !== 200) {
    Notification.error({
      title: message
    })
    return Promise.reject('error')
  } else {
    return res.data
  }
},
  error => {
    console.log('err' + error)
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

具体调用接口的位置。代码如下(根据自己项目的情况调整):

import { login} from 'unkApi/login'

...

// 登录
    Login({
      commit
    }, userInfo) {
      const username = userInfo.username.trim()
      const password = userInfo.password
      const code = userInfo.code
      const uuid = userInfo.uuid
      return new Promise((resolve, reject) => {
        login(username, password, code, uuid).then(res => {
          setToken(res.token)
          commit('SET_TOKEN', res.token)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

四、项目配置

在web.config添加一个是否采用离线缓存的开关,isoffline为true时采用离线缓存,这时就src\cacheApi里的接口调用,不走src\Api下的接口调用了:

...
const isOffline = true
const apiSrc = isOffline === true ? '/cacheApi' : '/api'
module.exports = {
...
  configureWebpack: {
    name: name,
    
    resolve: {
      //extensions: ['.js', '.vue', '.json'],
      alias: {
        //'vue$': 'vue/dist/vue.esm.js',
        '@': resolve('src'),
        'unkApi': resolve('src')+apiSrc, 
      }
    }
}
...

此方法完全可以用mock代替,并且mock的功能强大,还能完成更多其他的功能,项目较小并对依赖容量有要求,或者无法使用mock等其他拓展测试工具的场景可以参考一下,mock是捕获http请求后模拟接口的返回,而这种手写的方式不会发送请求,因为不走进request里面,写的比较粗糙,代码也比较老,觉得思路还可以的话,欢迎评论。

你可能感兴趣的:(笔记,前端)