【Vue-Element-Template】在登錄頁面按鈕上添加自己的api調用(二)


上一篇主要處理了頁面的布局以及路由問題

這篇主要處理在登錄頁面點擊按鈕,給后台api發請求的操作

涉及到的改動有以下部分:

1、utils目錄下新建myrequest.js文件   【這里主要模仿框架的request.js】封裝屬於自己的返回代碼和提示信息

utils目錄下此文件主要功能就是創建axion實例、初始化請求的base_url,另外就是設置request在發送請求前的一些操作和response收到請求后的一些操作。比如發請求前添加headers,收到請求后根據code值進行頁面跳轉或者提示

 

 

 

2、在api目錄下新建myuser.js文件【這里主要模仿框架的user.js】,這個api文件主要負責發送請求並返回請求的內容

 

 

 

3、在store文件夾--modules文件夾下還有個user.js    這里面定義了button點擊后form表單提交處理的邏輯

 

 

 

現在開始正題

a、因為要實現點擊登錄按鈕,調用api,所以先看mylogin的index頁面里,button綁定的事件:

<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登 錄</el-button>

可以看到綁定了handleLogin方法,此方法分兩部分,一部分為驗證表單輸入的正確性和必要性,另外一部分就是提交表單數據到某個地方了,可以看以下代碼

this.$store
            .dispatch('user/Mylogin', this.myLoginForm)
            .then(() => {
              this.$router.push({ path: this.redirect || '/' }) // 路由傳值,用於導航到下一個頁面 登錄成功之后重定向this.redirect或者'/'首頁
              this.loading = false
            })
            .catch(err => {
              this.$message.error(err) // 登錄失敗提示錯誤
              this.loading = false
            })

其中this.$store.dispatch('user/Mylogin', this.myLoginForm)就是將表單數據提交到了store--modules--user.js文件里的 Mylogin方法,原框架寫的是login方法提交成功后,就執行路由方法跳轉到下一頁面

 

b、下來接着看store--modules--user.js文件里的 Mylogin方法

參考原來的login方法,寫了自己的Mylogin方法,這個頁面我們引用了自己寫的user請求里的api_login以及api_logout,然后在Mylogin里調用了api_login並將表單的參數傳遞了進去

 
         
// import { login, logout, getInfo } from '@/api/user' // 框架原來自帶user相關api接口
import { api_login, api_logout } from '@/api/myuser' // 自己的user請求接口
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'

//
自己頁面的 login方法 Mylogin({ commit }, userInfo) { const { username, password } = userInfo // es6的寫法,可以用常量直接匹配等號后面的對象
// Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理
    return new Promise((resolve, reject) => {
      api_login({ username: username.trim(), password: password }).then(response => {
        const res = response // 將請求結果賦值給常量
        commit('SET_TOKEN', res.Result.token) // 設置store 狀態管理里面的token
        commit('SET_NAME', res.Result.name)
        commit('SET_AVATAR', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif')
        setToken(res.Result.token) // 設置token到cookie
        resolve() // 執行成功的方法
      }).catch(error => {
        reject(error) // 返回失敗的方法
      })
    })
  },

以下為修改后的user.js全文件

// import { login, logout, getInfo } from '@/api/user' // 框架原來自帶user相關api接口
import { api_login, api_logout } from '@/api/myuser' // 自己的user請求接口
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'

// 獲取用戶默認狀態
const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: ''
  }
}

const state = getDefaultState()

const mutations = {
  // 重置用戶狀態
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  // 用戶token
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  // 用戶姓名
  SET_NAME: (state, name) => {
    state.name = name
  },
  // 用戶圖像
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  }
}

const actions = {
  // user login
  // login({ commit }, userInfo) {
  //   const { username, password } = userInfo
  //   return new Promise((resolve, reject) => {
  //     login({ username: username.trim(), password: password }).then(response => {
  //       const { data } = response
  //       commit('SET_TOKEN', data.token)
  //       setToken(data.token)
  //       resolve()
  //     }).catch(error => {
  //       reject(error)
  //     })
  //   })
  // },

  // 自己頁面的 login方法
  Mylogin({ commit }, userInfo) {
    const { username, password } = userInfo
    // Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理
    return new Promise((resolve, reject) => {
      api_login({ username: username.trim(), password: password }).then(response => {
        const res = response // 將請求結果賦值給常量
        commit('SET_TOKEN', res.Result.token) // 設置store 狀態管理里面的token
        commit('SET_NAME', res.Result.name)
        commit('SET_AVATAR', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif')
        setToken(res.Result.token) // 設置token到cookie
        resolve() // 執行成功的方法
      }).catch(error => {
        reject(error) // 返回失敗的方法
      })
    })
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      api_logout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

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

c、因為上面調用了api_login,所以可以看看原來api目錄下的user.js   來寫我們自己的myuser.js里api_login方法

代碼里是我自己api請求的相關參數及命名,方法中主要給請求的url、類型、及data數據賦值 ,具體代碼如下:

import request from '@/utils/myrequest'

export function api_login(data) {
  return request({
    url: 'xxxxxxxxx/Login',
    method: 'post',
    data: {
      login_name: data.username,
      pwd: data.password,
      code: ''
    }
  })
}

export function api_logout(data) {
  return request({
    url: 'https://xxxxxxxxxx/LoginOut',
    method: 'post',
    data: {
      token: data.token
    }
  })
}
View Code

 

d、api_login中引用了utils文件夾中的request.js,所以我們也照貓畫虎創建一個自己的myrequest.js

// 導入axios請求封裝類
import axios from 'axios'
// 導入element的message及messagebox方法
import { MessageBox, Message } from 'element-ui'
// 導入自定義的store 狀態管理
import store from '@/store'
// 導入自定義工具類auth的獲取token方法
import { getToken } from '@/utils/auth'

// 創建實例 create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // 設置請求超時時間
})

// request請求攔截器
service.interceptors.request.use(
  config => {
    // 在request發送前做一些操作
    if (store.getters.token) {
      // 在這里添加可以使每個reqeust請求頭都帶上x-token這個屬性,可根據實際項目情況修改
      config.headers['X-Token'] = getToken()
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error) // 給Promise.reject()的失敗方法傳遞參數
  }
)

// Response的攔截器
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response.data
    // console.log(typeof (res.Code))
    // 如果api請求返回值code不是10000,說明請求出錯了. 請根據實際項目情況修改
    if (res.Code !== 10000) {
      // 側邊欄彈框提示消息
      Message({
        message: res.message || '收到請求后比較code值出現異常,請檢查大小寫', // 消息內容
        type: 'error', // success,error,info,warning 彈框類型
        duration: 5 * 1000 // 顯示時間
      })

      // 10004: Token expired;
      if (res.Code === 10004) {
        // 彈出登陸框重新登錄或取消
        MessageBox.confirm('Token已失效,可選擇重新登錄或取消', '提示:', {
          confirmButtonText: '重新登陸',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken') // 用戶點擊重新登陸時 跳轉到store下的user文件執行resetToken方法
            .then(() => {
              location.reload() // 執行成功后重新載入當前文檔
            })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res // 將成功的消息返回
    }
  },
  error => {
    console.log('err' + error) // for debug
    // 側邊欄彈框提示消息
    Message({
      message: error.message, // 消息內容
      type: 'error', // success,error,info,warning
      duration: 5 * 1000 // 彈框顯示時間
    })
    return Promise.reject(error)
  }
)

export default service
View Code

 

做完以上步驟整個調用就算是改完了。跑起來看看效果:

頁面提示Error,控制台中看到第一個錯誤提示是:[Vue warn]: data functions should return an object:      后來查詢了好久發現框架中res.code是小寫的,而我自己的api返回json中Code第一個字母是大寫的

 

 解決了這個問題之后,點擊登陸頁面沒再出現Error的錯誤。

 

但是又出現新的錯誤:

Login failed, unable to get user details,然后不停彈框  讓你點擊重新登錄或取消
 
這個錯誤是因為原框架中用了mock來模擬api請求並返回了模擬信息,在登錄成功后會調用getInfo往本地寫token、name、頭像信息等。這段代碼在原來的modules的user.js里面
因為getinfo是一個模擬請求,所以這里就把他個刪除了。然后把相關寫本地緩存的語句放到了Mylogin里面
 
這樣就可以在登錄后成功跳轉到dashboard頁面了

 


免責聲明!

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



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