axios請求與vuex


在上一篇利用vue-cli + vant搭建一個移動端開發模板的小文章中,我們簡易的搭建了一個使適用於h5開發的模板,很多細節的地方都是一帶而過。所以這邊短文會以圖文的形式,為大家展示vue項目開發過程中,從請求接口到頁面獲取數據,這一系列的流程中(請求接口、axios攔截、狀態管理、異常處理等)具體做了些什么。

源碼地址 (master分支為最新代碼,本文分支為2020/06/17)

流程圖

流程圖參考了vuex官網

一、Dispatch。

使用mapActions將store中我們需要的actions注入到組件中 (views\About.vue)

import { mapActions } from "vuex";
export default {
  created() {
    const parameter = {id: 1}
    this.getSomeData(parameter);
  },
  methods: {
    ...mapActions("some", ["getSomeData"])
  }
};

二、Action執行異步操作

在此Action中,執行請求接口的方法 (store\modules\some.js)

async getSomeData({ commit }, parameter) {
    console.log(parameter)
    const response = await getSomeDataApi(parameter)
}

三、通過二次封裝的axios請求接口

我們通過二次封裝axios,將公共的請求攔截,異常處理、請求頭等封裝起來統一操作。 (api\some.js)

import { axios } from '@/utils/request'
export function getSomeDataApi(parameter) {
  return axios({
    url: '/detail',
    method: 'get',
    params: parameter
  })
}

utils\request下對axios進行二次封裝

import axios from 'axios'
import { errorCode } from './errorCode'

// 創建 axios 實例
const service = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL, // api base_url
  timeout: 6000 // 請求超時時間
})

// 在異常處理中,我們可以 根據error.response.status返回的狀態碼進行操作,比如接口返回401作權限操作等
const err = (error) => {
  if (error.response) {
    if (error.response.status !== 200) {
      // 接口接口返回的狀態碼,獲取對應的提示消息
      const errorMessage = errorCode(error.response)
      console.log(errorMessage)
      return
    }
  }
  return Promise.reject(error)
}

// 請求攔截中,我們可以對請求頭作處理,比如所有的請求都加一個token等
service.interceptors.request.use(config => {
  // const token = 'token'
  // if (token) {
  //   config.headers['Access-Token'] = token // 讓每個請求攜帶自定義 token 請根據實際情況自行修改
  // }
  return config
}, err)

// 返回數據攔截中,我們可以對數據做一些小小的處理,比如后端所有接口返回的數據是這種類型:{data: {...}},那我們就可以把data這一層給過濾掉
service.interceptors.response.use((response) => {
  return response.data
}, err)


export {
  service as axios
}

上述代碼中,有個baseURL,其值我們可以通過.env這個文件中得到,這個玩意的作用相當於在所有的請求前加一個公共的地址。舉個例子:所有的接口前都需要加一個/api來供后台接口做轉發,我們肯定不會在所有的接口前一個一個加,那樣費事又費力,這個時候我們就可以用到baseURL了。

四、獲得返回的數據

我們在獲取數據后,如果想立刻獲得結果,可以通過傳遞一個callback參數的形式,從Action里callback到組件中。

1、修改Some.vue,添加callback參數

import { mapActions } from "vuex";
export default {
  created() {
    const parameter = {id: 1}
    this.getSomeData(parameter);
    this.doSomeCallback({
      parameter,
      callback: res => {
        console.log('這里是actions里callback回來的數據' + res)
      }
    });
  },
  methods: {
    ...mapActions("some", ["getSomeData", "doSomeCallback"])
  }
};

2、修改store\modules\some.js

async doSomeCallback({ commit }, { parameter, callback }) 
    const response = await getSomeDataApi(parameter)
    if (callback) callback(response)
 }

五、Commit

在Action里獲取到接口返回的數據時,我們可以通過commit這個方法,執行Mutation。修改store\modules\some.js

import { getSomeDataApi } from '@/api/some'

const mutations = {
  setSomeData: (state, data) => {
    console.log(data)
  }
}

const actions = {
  async getSomeData({ commit }, parameter) {
    console.log(parameter)
    const response = await getSomeDataApi(parameter)
    commit('setSomeData', response)
  },
  async doSomeCallback({ commit }, { parameter, callback }) {
    console.log(parameter)
    const response = await getSomeDataApi(parameter)
    commit('setSomeData', response)
    if (callback) callback(response)
  },
}

六、Mutate

更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。我們在獲取數據后,修改state里的值。最終store\modules\some.js的代碼

import { getSomeDataApi } from '@/api/some'

const state = {
  someData: ''
}

const mutations = {
  setSomeData: (state, data) => {
    // 為了演示效果我加了個Math.random()
    state.someData = data ? data : Math.random()
  }
}

const actions = {
  async getSomeData({ commit }, parameter) {
    console.log(parameter)
    const response = await getSomeDataApi(parameter)
    commit('setSomeData', response)
  },
  async doSomeCallback({ commit }, { parameter, callback }) {
    console.log(parameter)
    const response = await getSomeDataApi(parameter)
    commit('setSomeData', response)
    if (callback) callback(response)
  },
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

七、Render

在state里的值修改后,我們組件中綁定綁定的值如果改變了,頁面就會更新。修改Some.vue。

import { mapState } from "vuex";

computed: {
    ...mapState("some", ["someData"])
}

<div class="about">
    {{someData}}
</div>

最終我們的Some.vue的代碼如下所示

<template>
  <div class="about">
    <router-link to="/">Home</router-link>
    <Button type="primary" @click="doSomeCallback">點擊修改state里的值</Button>
    {{someData}}
  </div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { Button } from "vant";
export default {
  computed: {
    ...mapState("some", ["someData"])
  },
  created() {
    const parameter = { id: 1 };
    this.getSomeData(parameter);
    this.doSomeCallback({
      parameter,
      callback: res => {
        console.log("這里是actions里callback回來的數據" + res);
      }
    });
  },
  methods: {
    ...mapActions("some", ["getSomeData", "doSomeCallback"])
  },
  components: {
    Button
  }
};
</script>
<style lang="less">
.about {
  height: 100vh;
  font-size: 14px;
}
#detail {
  font-size: 14px;
}
</style>

vuex使用的注意點

優點:如果所有的接口走都vuex管理的話,有固定的流程,比較條理清晰,便於維護。

缺點:因為組件以及數據過多的情況,vuex內的數據也會越來越大,內存的占用也會越來愈大。

比較常用的使用vuex的情況:多個組件使用共同的接口數據(如后台管理某個下拉框的數據),應用的狀態管理(如h5應用內存儲用戶數據)等。。。

具體的可參考 一張圖弄明白 Vuex 里該存放什么樣的數據Should I Store This Data in Vuex – When Should I use Vuex?

總結

以上通過請求接口到頁面更新這一流程,向您展示了如何在項目里管理好axios請求與vuex。因本人文筆不太行,文章中可能會出現一些語句混亂的情況,望您諒解。(源碼在文章開頭)

感謝你的閱讀,如有修改或者建議的地方,歡迎提出哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM