vue+vuex+axios实现登录、注册页权限拦截

1、修改config文件夹里的dev.env.js里的BASE_API,把地址改成请求后端的公共部分

 
1
BASE_API: '"http://192.168.xx.xx"',

2、接下来就是操作src文件,先在 views里写好vew组件(login.vue,regist.vue),写好到router里的index.js里配置好路径

login.vue

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
< template >
  < div class = "login-container" >
   < el-form autoComplete = "on" :model = "loginForm" :rules = "loginRules" ref = "loginForm" label-position = "left"
      label-width = "0px"
      class = "card-box login-form" >
    < h3 class = "title" >登录</ h3 >
    < el-form-item prop = "name" >
   < span class = "svg-container svg-container_login" >
    < svg-icon icon-class = "user" />
   </ span >
     < el-input name = "name" disabled type = "text" v-model = "loginForm.name" autoComplete = "on"
       placeholder = "用户名" />
    </ el-form-item >
    < el-form-item prop = "password" >
   < span class = "svg-container" >
    < svg-icon icon-class = "password" ></ svg-icon >
   </ span >
     < el-input name = "password" :type = "pwdType" @ keyup.enter.native = "handleLogin" v-model = "loginForm.password"
       autoComplete = "on"
       placeholder = "密码" ></ el-input >
     < span class = "show-pwd" @ click = "showPwd" >< svg-icon icon-class = "eye" /></ span >
    </ el-form-item >
    < el-form-item >
     < el-button type = "primary" style = "width:100%;" :loading = "loading" @ click.native.prevent = "handleLogin" >
     登录
     </ el-button >
    </ el-form-item >
   </ el-form >
   </ div >
</ template >
< script >
  export default {
  name: 'login',
  data() {
   const validateUsername = (rule, value, callback) => {
   if (value.trim().length< 1 ) {
    callback(new Error('用户名不能为空'))
   } else {
    callback()
   }
   };
   const validatePass = (rule, value, callback) => {
   if (value.trim().length < 1 ) {
    callback(new Error('密码不能为空'))
   } else {
    callback()
   }
   };
   return {
   loginForm: {
    name: '',
    password: ''
   },
   loginRules: {
    name: [{required: true, trigger: 'blur', validator: validateUsername}],
    password: [{required: true, trigger: 'blur', validator: validatePass}]
   },
   loading: false,
   pwdType: 'password'
   }
  },
  methods: {
   showPwd() {
   if (this.pwdType === 'password') {
    this.pwdType = ''
   } else {
    this.pwdType = 'password'
   }
   },
   handleLogin() {
   this.$refs.loginForm.validate(valid => {
    if (valid) {
    this.loading = true;
    this.$store.dispatch('Login', this.loginForm).then(() => {
     this.loading = false;
     this.$router.push({path: '/'});
    }).catch((e) => {
     this.loading = false
    })
    } else {
    console.log('error submit!!')
    return false
    }
   })
   }
  }
  }
</ script >

router/index.js

 
1
{ path: '/login', component: _import('Login/login'), hidden: true }

3、在api里的login.js里写好与后端对接的接口地址,在stores里的modules里的user.js里定义user,有state,mutations,action,具体的请求操作写在action里,login.vue或regist.vue调用user.js里写好的请求,getter.js里定义store的getters

api/login.js

 
1
2
3
4
5
6
7
8
9
10
11
import request from '@/utils/request'
export function login(name,password) {
  return request({
  url: '/XX/XX',
  method: 'post',
  data: {
   name,
   password
  }
  })
}

stores/modules/user.js

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { login,regist,logout } from '@/api/login'
  import { getToken,setToken } from '@/utils/auth'
  const user = {
  state: {
   name:'',
   token:''
  },
  mutations: {
   SET_NAME: (state, name) => {
   state.name = name;
   },
   SET_TOKEN: (state, token) => {
   state.token = token;
   setToken(token);
   }
  },
  actions: {
   // 登录
   Login({ commit }, userInfo) {
   const name = userInfo.name.trim();
   const password = userInfo.password.trim();
   return new Promise((resolve, reject) => {
    login(name, password).then(response => {
    const data = response.data;
    commit('SET_NAME', data.name);
    commit('SET_TOKEN', data.token);
    setName(data.name);
    setToken(data.token);
    resolve(response); }).catch(error => { reject(error) }) }) },
   // 注册
   Regist({ commit }, userInfo) {
   const name= userInfo.name.trim();
   const password = userInfo.password.trim();
   return new Promise((resolve, reject) => {
    regist(name, password).then(response => {
    const data = response.data;
    commit('SET_NAME', data.name);
    commit('SET_TOKEN', data.token);
    setName(data.name);setToken(data.token);
    resolve(response);
    }).catch(error => {
    reject(error) }) }) },
   // 登出
   LogOut({ commit, state }) {
   return new Promise((resolve, reject) => {
   logout().then(response => {
    commit('SET_NAME', '');
    commit('SET_TOKEN', '');
    setName('');
    setToken(false);
    //removeName();
    //removeToken();
    resolve(response);
   }).catch(error => {
    reject(error)
   })
   })
  },
   // 前端 登出
   FedLogOut({ commit }) {
   return new Promise(resolve => {
  setToken(false);
commit('SET_TOKEN', false);
resolve()
   })
   }
  }
  }
  export default user

getter.js:

 
1
2
3
4
5
const getters={
  name:state=>state.user.name,
  token:state=>state.user.token
}
export default getter

4、在utils里的auth.js里对cookies进行操作,写入,读取,删除用户权限,是否登录的标志等

 
1
2
3
4
5
6
7
8
9
10
11
12
13
import Cookies from 'js-cookies'
export function setName(name) {
  return Cookies.set("name", name);
}
export function getName() {
  return Cookies.get("name");
}
export function setToken(token) {
  return Cookies.set("token", token);
}
export function getToken() {
  return Cookies.get("token");
}

5、在permission.js里写白名单,对白名单以外的跳转进行拦截然后跳转登录,同时判断用户权限,是否登录,等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import router from './router'
import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
import {Message} from 'element-ui'
import {getName, getToken} from "@/utils/auth"; // 验权
const whiteList = ['/login', '/regist']; // 不重定向白名单
router.beforeEach((to, from, next) => {
  NProgress.start();
  if (whiteList.indexOf(to.path) !== -1) {
  next();
  } else {
  if (getToken()==="true") {
   next();
   NProgress.done()
  } else {
   next({path: '/login'});
   NProgress.done()
  }
  }
})
router.afterEach(() => {
  NProgress.done() // 结束Progress
})

6、utils里的request.js里写拦截码,对后端返回的特定码进行拦截然后做相应的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
// 创建axios实例
const service = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 15000     // 请求超时时间
});
// respone拦截器
service.interceptors.response.use(
  response => {
  /**
  * code为非200是抛错 可结合自己业务进行修改
  */
  const res = response.data;
  //const res = response;
  if (res.code !== '200' && res.code !== 200) {
   if (res.code === '4001' || res.code === 4001) {
   MessageBox.confirm('用户名或密码错误,请重新登录', '重新登录', {
    confirmButtonText: '重新登录',
    cancelButtonText: '取消',
    type: 'warning'
   }).then(() => {
    store.dispatch('FedLogOut').then(() => {
     location.reload()// 为了重新实例化vue-router对象 避免bug
    })
   })
   }
   if (res.code === '4009' || res.code === 4009) {
   MessageBox.confirm('该用户名已存在,请重新注册!', '重新注册', {
    confirmButtonText: '重新注册',
    cancelButtonText: '取消',
    type: 'warning'
   }).then(() => {
    store.dispatch('FedLogOut').then(() => {
    location.reload()// 为了重新实例化vue-router对象 避免bug
    })
   })
   }
   return Promise.reject('error')
  } else {
   return response.data
  }
  },
  error => {
  Message({
   message: error.message,
   type: 'error',
   duration: 5 * 1000
  });
  return Promise.reject(error)
  }
)
export default service

猜你喜欢

转载自www.cnblogs.com/tis100204/p/10442771.html