天天看点

基于mpvue官方mpvue-quickstart 项目模板,配置fly+vuex+easymock实现多baseURL请求配置,mpvue+token拦截登录等功能

写这个配置的目的主要是 满足多baseURL请求需求,不喜欢使用 fly- get post那套 不可能傻乎乎的 每个 baseURL写一个 fly-get post;

我的项目地址https://gitee.com/ming34902/mpvue-quick-test1.git 放码云了,没有放github

基于mpvue官方mpvue-quickstart 项目模板,配置fly+vuex+easymock实现多baseURL请求配置,token拦截登录等功能,主要是方便 自己 后续 要是老板要求用坑爹 mpvue 写微信小程序 准备,本来用原生写的挺好的;

一、 准备工作

1. 下载mpvue官方mpvue-quickstart 项目模板,

http://mpvue.com/mpvue/quickstart/ 根据官方指引 自行安装 mpvue-quickstart 项目模板;

吐槽:官方mpvue2.0 之前版本 出现依赖报错问题,清空依赖 重新 npm install 都无法解决 百思不得其解,百度都找不出来,后面去github看mpvue的issues上才发现这问题是最近 mpvue更新出现 依赖bug报错,导致之前创建的几个mpvue初始项目模板丢弃,用mpvue2.0版本 以及mpvue-quickstart项目模板为基础 重新二次 配置自己想要的(fly多host请求,token拦截) 初始化的项目模板 ;

上述问题,mpvue2.0版本以下的项目 运行npm run dev(官方依赖问题)报错:

 [mpvue-loader] need "fileExt" option in file "build/vue-loader.conf.js"

Module build failed: Error: [mpvue-loader] need "fileExt" option in file "build/vue-loader.conf.js",init a new project and copy the directory "build/" to this porject, or just check the "fileExt" option
           

解决:使用mpvue2.0版本 以及mpvue-quickstart项目模板,重新写呗;

其他mpvue问题 就不多吐槽了,反正满头包.....

2. HTTP 请求终极解决方案flyio ,有些类似axios

https://wendux.github.io/dist/#/doc/flyio/readme flyio官方文档

3. easyMock 在线mock平台

就是不用写后台,直接自己创个项目 写接口配置(api+method+json)模拟后台api请求 返回数据,非常方便;

https://easy-mock.com

二、开始配置文件

假设你已准备好  mpvue-quickstart 项目模板文件,以及 微信web开发工具 appid 、easymock等;

1. 环境配置 config目录dev.env.js

var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  // BASE_API: '"https://ao-api-test.xxx.com"',
  BASE_API_UAA: '"https://easy-mock.com/mock/xxxx1/lisa-uaa"',  // 单点登录
  BASE_API: '"https://easy-mock.com/mock/xxx8/lisa-mpvue-test1"', // 提供常规业务需求 
})
           

2. flyio 写request.js 写请求,加了白名单、token拦截检查登录

import Fly from 'flyio/dist/npm/wx';
// import Fly from 'flyio' // 引用失败

// 获取白名单
import whiteList from '@/utils/whiteList';

const fly = new Fly();

//设置超时
fly.config.timeout = 20000;

// const Authorization = wx.getStorageSync('Authorization');

//添加请求拦截器
fly.interceptors.request.use((request) => {
  console.log('request', request);
  // 不显示加载页面的接口
  if (whiteList.loading.indexOf(request.url) === -1) {
    // 隐藏loading遮罩
  }
  wx.showLoading({
    'title': '加载中',
    'mask': true
  });
  // 请求资源服务器时,不添加token
  if (whiteList.nullHeaderToken.indexOf(request.url) !== -1) {
    request.timeout = 30000; // 请求超时
    request.headers = {
      'content-type': 'application/json',
      'X-Tag': 'flyio'
    };
    return request;
  }
  const Authorization = wx.getStorageSync('Authorization');
  // 延迟发请求 等 getStorageSync 存储
  setTimeout(() => {
    // 无token 则跳转登陆页
    if (Authorization) {
      // 给所有请求添加自定义header
      request.timeout = 30000;
      request.headers = {
        'content-type': 'application/json',
        'X-Tag': 'flyio',
        'Authorization': 'Bearer ' + Authorization
      };
    } else {
      // promise.reject(request)
      console.log('没有token跳转登录');
      setTimeout(() => {
        wx.redirectTo({
          url: '/pages/login/main'
        });
      }, 300)
    }
    return request;
  }, 300)
}, (error,promise) => {
  // Do something with request error
  console.log(error); // for debug
  promise.reject(error)
});

//添加响应拦截器,响应拦截器会在then/catch处理之前执行
fly.interceptors.response.use(
  (response) => {
    wx.hideLoading();
    console.log('interceptors数据', response.data);
    //只将请求结果的data字段返回
    return response.data
  },
  (err, promise) => {
    wx.hideLoading();
    let msg = '';
    if (err.status === 0) {
      msg = '网络连接异常'
    } else if (err.status === 1) {
      msg = '网络连接超时'
    } else if (err.status === 401) {
      msg = '用户未登录'
    } else {
      if (err.response.data.message) {
        msg = err.response.data.message
      } else {
        msg = '请求数据失败,请稍后再试'
      }
    }
    wx.showToast({
      title: msg,
      icon: 'none',
      duration: 2000
    });
    return promise.resolve(err)
  }
);
// Vue.prototype.$http=fly //将fly实例挂在vue原型上

export default fly
           

3. baseURLConfig.js

/**
 *  定义当前环境的各个API的 baseURL
 */
const baseURL = {
  'NORMAL': process.env.BASE_API,
  'UAA': process.env.BASE_API_UAA
};
export default baseURL;
           

4.业务api 多baseURL,api目录home.js

import fly from '@/utils/request'
import baseURL from '@/utils/baseURLConfig'
import qs from 'qs'

export function userLogin(data) {
  return fly.request({
    baseURL: baseURL.UAA, // 使用 BASE_API_UAA
    url: '/oauth/token',
    method: 'post',
    data: qs.stringify(data)
  })
}

export function getHomeList(data) {
  return fly.request({
    baseURL: baseURL.NORMAL, // 使用 BASE_API
    url: '/home/index',
    method: 'post',
    data: qs.stringify(data)
  })
}
           

5.常规使用- index.vue 首页

import * as HomeApi from '@/api/home'
export default {
  ....
  methods: {
    getData() {
      const toParams = { id: 1 } // 请求参数
      HomeApi.getHomeList(toParams).then((res) => {
        console.log('getHomeList()', res.data)
      }).catch((error) => { console.log(error) })
    },
  }
}
           

6.  vuex -action调用

store目录user.js

import { userLogin } from '@/api/user'
const user = {
  state: {
    token: '',
    name: '',
    openId: '初始openId',
    userInfo: {}
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token;
      wx.setStorageSync('Authorization', token);
    },
    SET_OPEN_ID: (state, openId) => {
      state.openId = openId;
      wx.setStorageSync('openId', openId);
    },
    SET_NAME: (state, name) => {
      state.name = name
    },
    SET_USER_INFO: (state, userInfo) => {
      state.userInfo = userInfo
    }
  },

  actions: {
    // 登录
    async Login({ commit }, userInfo) {
      // 方法一 async+await  成功
      const res_data = await userLogin(userInfo)
      commit('SET_TOKEN', res_data.data.access_token)
      commit('SET_OPEN_ID', res_data.data.openId)
      // 登录成功 跳转首页
      wx.switchTab({
        url: '/pages/index/main'
      });
    }
  }
}

export default user
           

具体使用login.vue

import { mapActions } from 'vuex'
export default {
  ....
  methods: {
      ...mapActions('user', [
        'Login'
      ]),
      async doLogin() {
        const that = this
        const check_res = that.checkLoginParams()
        if (check_res) {
          wx.showLoading({
            title: '登录中...', //提示的内容,
            mask: true, //显示透明蒙层,防止触摸穿透,
            success: (res) => { console.log(res) }
          });
          // 获取微信账号登录时的code
          let resCode = wx.getStorageSync('resCode')
          const params = {
            'code': resCode,
            'username': that.usernameInput,
            'password': that.pwdInput
          }
          await that.Login(params)
        }
      },
      // 账号 和 密码 校检
      checkLoginParams: function() {
        const that = this
        let {usernameInput, pwdInput} = that._data
        if (usernameInput === '') {
          wx.showToast({
            title: '请填写账号',
            icon: 'none',
            duration: 1500
          })
          return
        }
        if (pwdInput === '') {
          wx.showToast({
            title: '请填写密码',
            icon: 'none',
            duration: 1500
          })
          return
        }
        return true
      }
    }
  ....
}
           

三、文件目录结构注释md

|-- 项目
    |-- .babelrc             # 集成es6环境
    |-- .editorconfig        # 编辑器的配置
    |-- .eslintignore        # 表示忽略语法检查的目录文件
    |-- .eslintrc.js         # eslint 严格代码规范
    |-- .gitignore           # 表示文件内写好的文件路径都会被Git忽略,不会被提交到代码仓库
    |-- .postcssrc.js        # 对css前缀的一些解析
    |-- index.html           # 入口页面
    |-- package.json         # npm包配置文件,里面定义了项目的npm脚本,依赖包等信息
    |-- README.md            # 项目介绍
    |-- build                # 脚本目录
    |   |-- build.js           # 生产环境构建脚本
    |   |-- check-versions.js  # 运行本地构建服务器,可以访问构建后的页面
    |   |-- dev-client.js      # 开发服务器热重载脚本,主要用来实现开发阶段的页面自动刷新
    |   |-- dev-server.js      # 运行本地开发服务器
    |   |-- utils.js           # 构建相关工具方法
    |   |-- vue-loader.conf.js    # vue垫片配置
    |   |-- webpack.base.conf.js  # webpack配置文件
    |   |-- webpack.dev.conf.js   # webpack开发环境配置
    |   |-- webpack.prod.conf.js  # webpack生产环境配置
    |-- config             # 项目配置
    |   |-- dev.env.js     # dev开发环境
    |   |-- index.js       # 项目配置文件
    |   |-- prod.env.js    # prod生产环境
    |-- dist               # bulid 构建成功后 生产的目录
    |-- src                # 开发目录
    |   |-- app.json       # 路由、tab等配置
    |   |-- App.vue        # 根组件
    |   |-- main.js        # 预编译入口文件
    |   |-- api            # api接口目录
    |   |   |-- home.js
    |   |   |-- user.js
    |   |-- components     #  公共组件目录
    |   |   |-- card.vue
    |   |-- pages          #  页面目录
    |   |   |-- index        # 首页
    |   |   |   |-- index.vue
    |   |   |   |-- main.js
    |   |   |   |-- style.scss
    |   |   |-- login        # 登录页
    |   |   |   |-- login.vue
    |   |   |   |-- main.js
    |   |   |   |-- style.scss
    |   |   |-- logs         # 登录日志页
    |   |   |   |-- index.vue
    |   |   |   |-- main.js
    |   |   |   |-- main.json
    |   |   |-- search       # 搜索页
    |   |       |-- index.vue
    |   |       |-- main.js
    |   |       |-- style.scss
    |   |-- store             #  vuex目录
    |   |   |-- index.js      #  vuex 注册
    |   |   |-- modules       #  业务模块
    |   |       |-- home.js
    |   |       |-- user.js
    |   |-- style                # 样式目录
    |   |   |-- common.css
    |   |   |-- index.css
    |   |   |-- weui.css
    |   |-- utils                  # 工具目录
    |       |-- baseURLConfig.js   # baseURL配置
    |       |-- global.js          # 全局数据存储 global
    |       |-- index.js           #
    |       |-- request.js         # fly 请求
    |       |-- wechat.js          #  wechat微信原生api
    |       |-- whiteList.js       #  请求白名单
    |       |-- common             # 公共类
    |       |   |-- mixins.js
    |       |   |-- tips.js
    |       |   |-- utils.js
    |       |-- lib               # 图书馆
    |           |-- amap-wx.js    # 高德-wx
    |-- static                    # web静态资源加载目录 不会被wabpack构建
        |-- images
            |-- common
            |-- tabs
           

继续阅读