npm i axios
## vue提示
npm i vant
public
資料夾下新增data.json
{
"token": "requestToken",
"todolist": [
{
"id": 1,
"title": "Html",
"content": "This is html",
"status": true
},
{
"id": 2,
"title": "CSS",
"content": "This is css",
"status": false
}
]
}
src
下新增api
資料夾和index.js
和base.js
檔案 | 功能 |
---|---|
index | 1.封裝 axios 2.斷網情況處理 請求和響應攔截 |
base | 接口域名有多個情況 |
import axios from 'axios'
import store from '@/store'
import router from '@/router'
import { Toast } from 'vant'
/**
* 提示函数
* 禁止點擊蒙層、顯示一秒後關閉
*/
const tip = msg => {
Toast({
message: msg,
duration: 1000,
forbidClick: true
})
}
/**
* 跳轉登錄頁
* 攜帶當前頁面路由,以期在登錄頁面完成登錄後返回當前頁面
*/
const toLogin = () => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}
/**
* 請求失敗後的錯誤統一處理
* @param {Number} status 請求失敗的狀態碼
*/
const errorHandle = (status, other) => {
// 狀態碼判斷
switch (status) {
// 401: 未登錄狀態,跳轉登錄頁
case 401:
toLogin()
break
// 403 token過期
// 清除token並跳轉登錄頁
case 403:
tip('登錄過期,請重新登錄')
localStorage.removeItem('token')
store.commit('loginSuccess', null)
setTimeout(() => {
toLogin()
}, 1000)
break
// 404請求不存在
case 404:
tip('請求的資源不存在')
break
default:
console.log(other)
}
}
// 創建axios實例
var instance = axios.create({ timeout: 1000 * 12 })
// 設置post請求頭
instance.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded'
/**
* 請求攔截器
* 每次請求前,如果存在token則在請求頭中攜帶token
* 透過瀏覽器的 Network中,在 Request Headers可觀察 Authorization
*/
instance.interceptors.request.use(
config => {
// 登錄流程控制中,根據本地是否存在token判斷用戶的登錄情況
// 但是即使token存在,也有可能token是過期的,所以在每次的請求頭中攜帶token
// 後台根據攜帶的token判斷用戶的登錄情況,並返回給我們對應的狀態碼
// 而後我們可以在響應攔截器中,根據狀態碼進行一些統一的操作
const token = store.state.token
// 如果token有值,才做設定
token && (config.headers.Authorization = token)
return config
},
error => Promise.error(error)
)
// 響應攔截器
instance.interceptors.response.use(
// 請求成功
res => (res.status === 200 ? Promise.resolve(res) : Promise.reject(res)),
// 請求失敗
error => {
const { response } = error
if (response) {
// 請求已發出,但是不在2xx的範圍
errorHandle(response.status, response.data.message)
return Promise.reject(response)
} else {
// 處理斷網的情況
// eg:請求超時或斷網時,更新state的network狀態
// network狀態在app.vue中控制著一個全局的斷網提示組件的顯示隱藏
// 關於斷網組件中的刷新重新獲取數據,會在斷網組件中說明
if (!window.navigator.onLine) {
store.commit('CHANGE_NETWORK', false)
} else {
return Promise.reject(error)
}
}
}
)
export default instance
/**
* 接口域名的管理
*/
const base = {
dev: 'data.json',
prod: 'data1.json'
}
export default base
import Vue from 'vue'
import Vuex from 'vuex'
import axios from '@/api' // 導入http中創建的axios實例
import base from '@/api/base' // 導入接口域名列表
import todolist from '@/store/module/todolist'
Vue.use(Vuex)
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production',
state: {
token: null,
network: true
},
modules: {
todolist
},
mutations: {
GET_TOKEN(state, data) {
state.token = data
},
CHANGE_NETWORK(state, val) {
state.network = val
}
},
actions: {
// 取得 token
getToken({ commit }) {
axios.get(`${base.dev}`).then(res => {
commit('GET_TOKEN', res.data.token)
})
}
}
})
加上
import api from '@/api'
// 將api掛載到vue的原型上
// 目的讓各 component也能直接使用
Vue.prototype.$api = api
import axios from '@/api' // 導入http中創建的axios實例
import base from '@/api/base' // 導入接口域名列表
const state = {
list: []
}
const mutations = {
GET_TOLIST(state, data) {
state.list = data
}
}
const actions = {
getTodoList({ commit }) {
axios.get(`${base.dev}`).then(res => {
commit('GET_TOLIST', res.data.todolist)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
可以使用$api
讀取資料,如
this.$api.get(`${base.prod}`).then(res => {
console.log(res.data.todolist)
})
因為使用vuex
模組化,使用注意為
this.$store.dispatch('todolist/getTodoList')