很久沒搞 Vue 了,之前都是很隨便的糊 Vue 代碼,此次認真糊了一下,發出來給帶家一塊兒回顧一下康康對不對 致力於 CV 推廣,CV 越快,下班越快javascript
這裏只作最簡潔的也比較實用的配置,各位帶佬根據本身的實際需求去修改vue
在 src 目錄下新建 store 文件夾,裏面再建兩個文件,store.js 和 md_wxuser.jsjava
個人主文件基本上都跟文件夾同名,若是我用 index 替代 store以及其餘文件也是這樣的風格,這會讓我在文件欄那裏看到一堆的 index.js,切換文件時會發現,這踏馬一堆的 index.js 誰是誰啊,如下其餘文件也是如此webpack
// md_user.js
const UPDATEWXUSER = 'UPDATEWXUSER' // 我也不知道爲何要這樣寫,你們都這麼寫我也就這麼寫了,有沒有帶佬給弟弟我解釋一下
export default {
state: {
// 不是在微信開發者工具裏測試或開發登陸功能時,我會把 wxuser 給註釋掉,把下面註釋掉的放出來,這樣就直接在 Chrome 裏面開發就能夠了
wxuser: null,
// wxuser: {
// nickname: 'WSND',
// sex: '1',
// province: '廣東',
// city: '深圳',
// country: '中國',
// unionid: 'xxxxxxxxxxxxxxxxxxxx',
// role: 'lecturer',
// access_token: 'dddddddddddddddddddd'
// }
},
mutations: {
// 這裏寫個 mutation,以後會在 vue-router 的生命週期裏面使用
// 存儲微信用戶信息
[UPDATEWXUSER](state, value) {
state.user = value
}
},
actions: {
// 習慣了用 actions 來 commit mutation,actions 作數據更新操做可使用 async await 的好處等等。
updateWxuser({ commit }, value) {
commit(UPDATEWXUSER, value)
}
},
getters: {
// 就返回上面的 wxuser 沒啥好講的......
wxuser: state => state.wxuser
}
}
複製代碼
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
import md_wxuser from './md_user.js' // 導入上面咱們寫好的 md_user.js
Vue.use(Vuex)
const store = new Vuex.Store({
modules:{ // 使用 modules 方式創建 store 之後項目大了會讓你的項目比較清晰
wxuser: md_user
}
})
export default store
複製代碼
vuex 的配置到此結束ios
在 src 文件夾下創建 api 文件夾,文件夾下創建三個文件,http.js,install.js,interface.jsweb
// http.js
import axios from 'axios'
import QS from 'qs'
import store from '../store/store' //導入 Vuex store,
import { Toast } from 'vant' // 導入 vant 的提示組件
// 請求超時時間 -> 1分鐘
axios.defaults.timeout = 60000
// 請求攔截器
axios.interceptors.request.use(
config => {
const { access_token } = store.getters.wxuser || {} // 假設你與後臺通訊驗證是 access_token 字段
// 驗證沒那麼高要求的基本上都是在 header 配置的吧,可能大家配置 token 或者 openid,這裏舉例 access_token
config.headers['access_token'] = access_token || ''
// 這裏舉個這個例子想告訴你們配置都不必定要按照我全部的代碼
// 具體看大家實際的方案來改,給你們展現的只是一個思路
// 本身能夠靈活更改一點,此處由於咱們的後臺須要我 access_token 經過 post 請求 header 爲 content-type
// application/x-www-form-urlencoded 透過 post 的 data 傳過去
// config.data = QS.stringify({
// ...QS.parse(config.data),
// access_token
// })
return config
},
error => {
return Promise.error(error)
}
)
// 響應攔截器
axios.interceptors.response.use(
response => {
if (response.status === 200) {
// 這裏看我的需求,若是後端規範的話,就在這裏作 Toast 輕提示,這裏的 Toast 用的是 vant 的組件
// const { code, msg } = response.data
// if (code === -1) {
// Toast.fail(msg)
// }
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
// 服務器狀態碼不是200的狀況
error => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '請求錯誤'
break
case 401:
error.message = '未受權,請登陸'
break
case 403:
error.message = '拒絕訪問'
break
case 404:
error.message = `請求地址出錯: ${error.response.config.url}`
break
case 408:
error.message = '請求超時'
break
case 500:
error.message = '服務器內部錯誤'
break
case 501:
error.message = '服務未實現'
break
case 502:
error.message = '網關錯誤'
break
case 503:
error.message = '服務不可用'
break
case 504:
error.message = '網關超時'
break
case 505:
error.message = 'HTTP版本不受支持'
break
default:
error.message = '請求錯誤'
break
}
}
// Toast 提示錯誤
Toast.fail(error.message)
return Promise.reject(err)
}
)
// get 和 post 方法都用 Promise 封裝,resolve 和 reject 拿到響應數據或處理錯誤
/** * get方法,對應get請求 * @param {String} url [請求的url地址] * @param {Object} params [請求時攜帶的參數] */
export function get(url, params) {
return new Promise((resolve, reject) => {
axios
.get(url, {
params: params
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
/** * post方法,對應post請求 * @param {String} url [請求的url地址] * @param {Object} params [請求時攜帶的參數] */
export function post(url, params) {
return new Promise((resolve, reject) => {
// 防呆解釋,這裏我把 params 格式化是由於咱們的後臺要求 Content-Type 爲 application/x-www-form-urlencoded
// 若是大家的 Content-Type 爲 application/json 的話就不用作 QS.stringify(params) 的處理
let data = QS.stringify(params)
axios({
url,
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
複製代碼
// interface.js
// 這個文件只舉簡單的例子
import { get, post } from './http' // 導入咱們封裝好的 get post
// 懶得在 dev prod env 設置 BASE_URL 的同窗 直接在這裏寫吧
const BASE_URL = 'http://192.168.1.xxx:8040'
// 這裏 return 回來的是咱們直接寫的 post,post return 出來的就是 Promise對象,那麼 loginAndGetUser return 回來了 Promise,
// 咱們就能夠在組件裏用 await 的方式簡潔的寫,let res = await this.$api.loginAndGetUser(),
// 在業務裏減小回調能夠幫咱們更好的理解代碼,有時候 await 也可讓咱們按順序完成異步請求
export const loginAndGetUser = params => {
return post(`${BASE_URL}/getWaitChat`, {
...params
})
}
// 這裏咱們導出一個對象方便裝在 Vue 上調用
export default {
loginAndGetUser
}
複製代碼
// install.js
import apiList from './interface'
const install = Vue => {
if (install.installed) return
install.installed = true
Object.defineProperties(Vue.prototype, {
// 此處掛載在 Vue 原型的 $api 對象上
// 在組件實例裏面 直接 this.$api.loginAndGetUser() 調用Api
$api: {
get() {
return apiList
}
}
})
}
export default install
複製代碼
src 下新建 router 文件夾,文件夾下新建 router.js 文件vue-router
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store/store' // 導入 store
import { post } from '../api/http' // 導入封裝好的 post
import { Dialog } from 'vant' // 此處本人最近的項目須要,非必須
Vue.use(Router)
const router = new Router({
mode: 'history',
base: 'msgmanage',
// 提醒,用了 base,記得去/config/index.js 下面 assetsPublicPath
// 改成 '/xxxxxx/' 這裏的xxxx跟你的 base 同名,例如 assetsPublicPath:
// '/msgmanage/',理解不了的去問大家的後端爲何這樣作,這裏不作解釋
routes: [
{
path: '/',
name: 'index',
component: () => import('../pages/index/index.vue')
}
]
})
// 在 router 裏作登陸處理
// 微信網頁登陸原理這裏就不講了,只講怎麼優化流程
router.beforeEach(async (to, from, next) => {
const appid = 'xxxxxxxxxxxxxxxxxx' // 你的公衆號appid
const redirect_uri = `${window.location.href}` // redirect_uri 至關於訪問的域名,這樣寫就能夠了
const {
query: { code = null }, // 根據實際須要,這裏能夠只把 url 裏的 code 結構出來就能夠了
name,
path,
meta
} = to // to 裏面的對象能夠自行打印出來,取出你會用到的東西
// 咱們以前在 vuex store 裏存儲了 wxuser 數據頁面一刷新,wxuser就沒了,因此咱們這裏作一下頁面本地存儲
// 若是刷新頁面的話直接從 sessionStorage 讀回來,
if (sessionStorage.getItem('wxuser')) {
// 存儲用戶信息
store.dispatch('updateUserInfo', JSON.parse(sessionStorage.getItem('wxuser')))
}
// 若是咱們是正常進來這裏的 wxuser 是 null
const wxuser = store.getters.user
// 咱們在本地作開發的時候上面的 wxuser 就不是 null ,不會執行這裏面的微信網頁登陸業務邏輯
if (wxuser === null) {
// 若是沒有 code 跳轉 獲取 code
if (!code) {
return (window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect`)
}
// 用微信的 code 跟後臺登陸,把data 和 result 解構出來
let { data, result } = await post(
'http://192.168.1.xxx:8040/login',
{
code
}
)
// 咱們後臺規定正常和成功的請求時result.errCode的值爲0
if (result.errCode === 0) {
// 防止頁面刷新作的存儲,對應上面的頁面刷新先讀取sessionStorage
sessionStorage.setItem('wxuser', JSON.stringify(data))
// 存儲至 vuex store
store.dispatch('updateUserInfo', data)
} else {
// 我的業需求 未受權使用 vant 的 Dialog 組件提示 而且 return 直接頁面白屏中斷後續
Dialog.alert({
title: '未受權',
message: `您的受權碼是 ${result.errMsg} 複製您的受權碼發送給管理員完成受權後從新打開該網頁`
})
return
}
}
next() // 不要忘了 next()
})
export default router
複製代碼
要在微信開發者工具正常使用微信跳轉微信登陸須要修改 webpack 的配置以及本地系統上的 hosts 靜態映射vuex
// /config/index.js
module.exports = {
dev: {
host: '192.168.1.140', // 改成你本地的ip地址
port: 80,// 端口改成 80 端口
}
}
複製代碼
// /build/webpack.dev.conf.js
const devWebpackConfig = merge(baseWebpackConfig, {
devServer: {
disableHostCheck: true // 加上這個屬性
}
})
複製代碼
// 本地系統 hosts 文件
192.168.1.140 xxx.testest.com
# 這裏的 xxx.testest.com 域名去找大家後端拿,不給你就讓他爬,其餘的方法弟弟我也不懂
# 在微信開發者網頁開發模式瀏覽器地址欄直接輸入xxx.testest.com 就能夠映射到你的項目了
複製代碼
最後這裏直接粘貼複製吧,沒啥好講的json
import Vue from 'vue'
import App from './App'
import router from './router/router' // 導入 router
import store from './store/store' // 導入 vuex 的 store
import api from './api/install' // 導入接口
import vant from 'vant' // vant 挺好用的,推薦使用
Vue.use(vant)
Vue.use(api)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
複製代碼