天天看點

基于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
           

繼續閱讀