vue-element-admin登陸模塊和axios踩坑


最近在做公司的一個后台管理項目,用了vue admin來搭建項目的前端,本人也是個vue的新手,很多都不太理解,各種百度,才搞懂了整個登陸流程接口的替換,因此在此記錄一下。

所有的重點我都會在代碼中的注釋里說明。

一、登陸接口的替換

//這段代碼是src/api/user.js中的代碼
import request from '@/utils/request'

export function login(data) {
  return request({
    // 這里替換成自己的登陸接口,下面的也是一樣
    url: '/login',
    method: 'post',
    data
  })
}

export function getInfo(otherQuery) {
  return request({
    url: '/getInfo',
    method: 'get',
    params: otherQuery
  })
}

export function logout() {
  return request({
    url: '/vue-admin-template/user/logout',
    method: 'post'
  })
}

login()方法那里,url只需要替換成自己登陸接口地址就行,不要帶上接口的IP地址或者域名。然后,頂部我們注意到,有一個import request from '@/utils/request',這是request文件,也就是我們request方法的定義,讓我們來看下文件里的一段代碼:

const service = axios.create({
  // 這里替換成自己接口的服務器地址,並且把.env.development中的VUE_APP_BASE_API參數置為空
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 5000 // request timeout
})

可以看到,baseURL那里需要換成自己的接口地址才算全部替換完成。

二、接口調用以及response的處理

可能有些小伙伴會覺得奇怪,怎么換了接口還是登陸不進去頁面呢?這是因為還沒調用接口方法。
整個登陸流程的接口調用,包括登陸、獲取用戶信息、登出等步驟,都在@/store/modules/user中進行了調用,而各種登陸信息的存儲,也都在此文件中操作。我們來看下代碼:

import { login, logout, getInfo } from '@/api/user'//這里便引用了我們說的接口方法文件,即第一點登陸接口替換那部分文件代碼
import { getToken, setToken, removeToken } from '@/utils/auth'//這個文件不用管,是已經封裝好的關於token的幾個方法
import router, { resetRouter } from '@/router'
//state和mutations里按需進行刪除和添加,比如說,如果你需要存儲一個用戶id字段用於后續接口,直接添加進來,用this.$store.state.user.id便可在后續文件中引用
const state = {
  token: getToken(),
  name: '',
  avatar: '',
  introduction: '',
  roles: []
}

const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_INTRODUCTION: (state, introduction) => {
    state.introduction = introduction
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_ROLES: (state, roles) => {
    state.roles = roles
  }
}

const actions = {
  login({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      //此處的login()方法便是@/api/user中的login()方法,username和password根據后台提供的接口進行參數替換
      login({ username: username.trim(), password: password }).then(response => {
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {//如果前期不需要用戶信息,可直接把大括號外部注釋掉,留大括號里的內容(即const開頭那部分內容),data用假數據
        const { data } = response

        if (!data) {
          reject('Verification failed, please Login again.')
        }

        const { roles, name, avatar, introduction } = data

        if (!roles || roles.length <= 0) {
          reject('getInfo: roles must be a non-null array!')
        }

        commit('SET_ROLES', roles)
        commit('SET_NAME', name)
        commit('SET_AVATAR', avatar)
        commit('SET_INTRODUCTION', introduction)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  logout({ commit, state, dispatch }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {//這里也是同理,不需要便注釋,留下大括號內的內容同樣可以清除token登出
        commit('SET_TOKEN', '')
        commit('SET_ROLES', [])
        removeToken()
        resetRouter()

        dispatch('tagsView/delAllViews', null, { root: true })

        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  resetToken({ commit }) {
    return new Promise(resolve => {
      commit('SET_TOKEN', '')
      commit('SET_ROLES', [])
      removeToken()
      resolve()
    })
  },
}

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

登陸流程的接口調用流程改完之后,我們便可以進去首頁了。

如果還是進不去,便到login.vue和@/utils/validate中修改驗證信息即可。

接下來是返回數據response的處理。我們先來看看request文件的剩余部分:

service.interceptors.request.use(
  config => {
    // 這里是將獲取到的token放在請求頭里
    if (store.getters.token) {
      // 每一個request都將帶上token,這里的X-Token可根據后端的設定或者瀏覽器的要求來改
      config.headers['X-Token'] = getToken()
    }
    return config
  },
  error => {
    console.log(error) 
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    const res = response.data
    // 這里記得將code改為自己的code
    if (res.code !== 20000) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        // 這是請求的時長,可以設置的長一些,不然請求時間久的話,超過這個時長就會報錯
        duration: 5 * 1000
      })

      // 這里也可按自己的需要去更改
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
          confirmButtonText: 'Re-Login',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error) 
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

需要注意的是,上述代碼中的response是包含了請求頭在內的response,而res只是取了數據部分,如果不進行修改,后續接口的調用是獲取不到headers的。如果后續需要獲取請求頭,也要在這里按需修改。

三、其他接口的調用及axios踩坑

上面已經將登陸部分接口相關的內容全部講完,接下來是講述除登陸以外的接口我們要怎么去調用。
其實看完整的vue-element-admin模版便可以發現,所有的接口信息都儲存在@/api之下的js文件中,而vue文件中如果要調用的話,則可按以下步驟來:

//@/api/article是api文件夾下的article.js文件,存放了fetchList這個接口方法,用import引入這個方法
import { fetchList } from '@/api/article'

methods: {
    getList() {
      this.listLoading = true
      //這里便可引用fetchList方法進行接口調用
      fetchList(this.listQuery).then(response => {
        this.list = response.data.items
        this.total = response.data.total
        this.listLoading = false
      })
    }
  }

看完接口調用步驟之后,我要說一下新手容易踩的一個axios坑,拿登陸和用戶信息接口為例來講:

export function login(data) {
  return request({
    url: '/vue-element-admin/user/login',
    method: 'post',
    data
  })
}

export function getInfo(token) {
  return request({
    url: '/vue-element-admin/user/info',
    method: 'get',
    params: { token }
  })
}

我們可以看到,登陸接口是post方法,而參數傳遞如果只是一個data的話,其實是相當於用data:data這樣的形式來傳遞的參數。

而在axios中,data:xxx是表示傳遞的參數不采用拼接的方式傳遞,params:xxx則相反。

這點讓還是新手的我踩了不少坑,因為我在這里特別標注以下,以防有像我這樣的新手再踩坑。


免責聲明!

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



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