【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