页面切换
我做的后台页面较少,所以不需要用到路由
1.登录后切换到老师或者学生的页面,通过is_admin来判断登录的是老师还是学生
-
data(){
-
return{
-
login:
false
-
}
-
}
-
<Author v-if="!login">
</Author>
-
<div v-else>
-
学生或者老师的页面
-
</div>
2.问题:无论成功或者失败,都是走成功的回调函数,怎么解决呢?
通过promise
-
//拦截器 回复
-
api.interceptors.response.use(
response=>{
-
return response.data.data;
-
},error=>{
-
const response=error.response;
-
Vue.$notification.error({
-
message:
"API Error",
-
description:response.data.errorMessage
-
});
-
//加上这句
-
return
Promise.reject(error);
-
})
报错,因为我并没有写失败的回调函数

3.子组件通过自定义事件往父组件传值
子组件:
-
submit(){
-
//地址,参数
-
api.post(
"/auth/login",
this.form).then(
data=>{
-
console.log(data);
-
this.$emit(
"changeLog");
-
});
-
}
父组件:
<Author v-if="!login" @changeLog="login=true"></Author>
4.通过Vuex来传值
4.1.在store下面新建modules文件夹,然后新建文件user.js
声明四个变量,然后暴露出去
-
const state = {
-
-
-
}
-
const getters = {
-
-
}
-
-
const mutations = {
-
-
}
-
-
const actions = {
-
-
}
-
-
export
default {
-
state,
-
getters,
-
mutations,
-
actions
-
}
4.2.在store.js中怎么使用user.js文件呢?
两步,一:引入,二:在模块中定义
-
import Vue
from
'vue'
-
import Vuex
from
'vuex'
-
import user
from
'./modules/user'
-
Vue.use(Vuex)
-
-
export
default
new Vuex.Store({
-
state: {
//状态
-
},
-
mutations: {},
-
actions: {},
-
modules: {
-
user
-
}
-
})
4.3.为了避免模块在融合的时候,起了冲突,要加上命名空间:namespaced的概念
在user.js中
-
export
default {
-
namespaced:
true,
-
state,
-
getters,
-
mutations,
-
actions
-
}
4.4.在user.js中定义login
-
const state = {
-
login:
false
-
}
在App.vue中通过计算属性监听login可以使用到这个定义的login
-
computed:{
-
login(){
-
return
this.$store.state.user.login
-
}
-
}
4.5.怎么把数据进行改变呢?
点击提交向后台发送请求,但是请求是异步的,通过dispatch去触发action
-
submit(){
-
//地址,参数
-
api.post(
"/auth/login",
this.form).then(
data=>{
-
console.log(data);
-
this.$store.dispatch(
'login',
this.form);
-
});
-
}
在user.js中看有没有触发,打印一下
-
const actions = {
-
//context为环境对象
-
login({ commit }, form) {
-
console.log(form);
-
}
-
}
报错,是因为命名空间的关系,都隔了一层,要加上user,要加什么看你怎么命名
-
submit(){
-
//地址,参数
-
api.post(
"/auth/login",
this.form).then(
data=>{
-
console.log(data);
-
this.$store.dispatch(
'user/login',
this.form);
-
});
-
}
这样就可以把form传到user.js中
遇到一个问题:我定义却没有使用,ESLint会报我错误,目前的解决办法只有在安装的时候不安装ESLint
4.6.怎么把login的false变成true,在user.js中
当我们提交用户和密码时,要触发一个actions,发送ajax请求,请求成功的话,要把login的状态变成true
-
import { api }
from
"../../utils/api";
-
const mutations = {
-
loginon(state) {
-
state.login =
true;
-
}
-
}
-
-
const actions = {
-
//context为环境对象
-
login({ commit }, form) {
-
console.log(commit);
-
api.post(
"/auth/login", form).then(
result => {
-
console.log(result);
-
commit(
"loginon");
-
});
-
}
-
}
4.7.怎么切换成老师或者学生的界面
在user.js中先是在state里面定义info,接着在actions来commit这result,最后在mutations里面去赋值。
-
import { api }
from
"../../utils/api"
-
const state = {
-
login:
false,
-
//存信息
-
info:{
-
-
}
-
}
-
const getters = {
-
-
}
-
-
const mutations = {
-
loginon(state,data) {
-
state.login =
true;
-
state.info=data;
-
}
-
}
-
-
const actions = {
-
//context为环境对象
-
login({ commit }, form) {
-
console.log(commit);
-
api.post(
"/auth/login", form).then(
result => {
-
console.log(result);
-
commit(
"loginon",result);
-
});
-
}
-
}
要在App.vue中去使用这个登录信息,要先拿到info
-
computed:{
-
login(){
-
return
this.$store.state.user.login
-
},
-
info(){
-
return
this.$store.state.user.info
-
}
-
}
然后再渲染出来

学生的is_admin为0,老师的is_admin为1
-
computed:{
-
isTeacher(){
-
return
this.info.is_admin>
0
-
}
-
},
-
components: {
-
Author
-
-
}
当isTeacher为true的时候,切换到老师页面,
当isTeacher为false的时候,切换到学生页面。
-
<div v-else>
-
<Teacher v-if="isTeacher">
</Teacher>
-
<Student v-else>
</Student>
-
</div>
4.8.辅助函数的使用
-
<script>
-
import {mapState}
from
"vuex"
-
-
export
default {
-
computed:{
-
//获取user下面的info,不然会默认找到store下面
-
...mapState(
"user",[
"info",
"login"]),
-
// login(){
-
// return this.$store.state.user.login
-
// },
-
// info(){
-
// return this.$store.state.user.info
-
// },
-
-
}
-
-
}
-
</script>
自动登录
点击登录的时候把状态存到localStorage中
键值的形式,我们要传对象,会存两个值,它会把他转成字符串,所以要用JSON.stringify
在user.js中
-
const mutations = {
-
loginon(state, data) {
-
state.login =
true;
-
state.info = data;
-
//键值的形式,我们要传对象,会存两个值,它会把他转成字符串,所以要用JSON.stringify
-
localStorage.setItem(
"eStudy",
JSON.stringify({
login:
true,
info:
JSON.stringify(data) }))
-
}
-
}
使用前要清空一下数据,然后点击登录,测试有没有存成功

在这底下可以看到存的login和info

在user.js中怎么从localStorage中取值呢?
要先解析字符串,也有可能取不到值
-
const eStudy =
JSON.stringify(localStorage.getItem(
"eStudy")) || {};
-
const state = {
-
login: eStudy.login ||
false,
-
info: eStudy.info ?
JSON.parse(eStudy.info) : {}
-
}
我们自己去存localStorage,并且自己去取,其实是挺麻烦的
可以使用插件
1.下载
npm install vuex-persistedstate --save
plugins是vuex的插件
如果我们去提交mutations,那它会把mutations里面的值全部存到localStorage
2.使用
在store的index.js中,要先引入,然后在plugins里面配置
-
import Vue
from
'vue'
-
import Vuex
from
'vuex'
-
import user
from
'./modules/user'
-
import createPersistedState
from
'vuex-persistedstate'
-
Vue.use(Vuex)
-
-
export
default
new Vuex.Store({
-
-
modules: {
-
user
-
},
-
plugins:[
-
createPersistedState({
-
-
})
-
]
-
})
并不是所有的数据都要存在localStorage,写模块化就可以避免这种情况,我们只把登录的相关信息存到user里面

-
import Vue
from
'vue'
-
import Vuex
from
'vuex'
-
import user
from
'./modules/user'
-
import createPersistedState
from
'vuex-persistedstate'
-
Vue.use(Vuex)
-
-
export
default
new Vuex.Store({
-
-
modules: {
-
user
-
},
-
plugins: [
-
createPersistedState({
-
key:
"eStudy",
-
paths: [
"user"]
-
})
-
]
-
})
自动登录到这边就做完了,
但是自动登录是要有时间限制的,通过验证token过没过期,来决定是否可以登录
订阅函数:当前的mutation和localStorage之间的关系,subscriber,初始化的钩子函数
-
import Vue
from
'vue'
-
import Vuex
from
'vuex'
-
import user
from
'./modules/user'
-
import createPersistedState
from
'vuex-persistedstate'
-
Vue.use(Vuex)
-
-
export
default
new Vuex.Store({
-
-
modules: {
-
user
-
},
-
plugins: [
-
createPersistedState({
-
key:
"eStudy",
-
paths: [
"user"],
-
subscriber(store) {
-
return
function(handler) {
-
return store.subscribe(handler);
-
}
-
}
-
})
-
]
-
})
我们的token的接口是7天,7天没登就过期了,在第六天登录了,还能在续期7天。
看一下接口的请求参数:

在user.js中
-
const actions = {
-
//context为环境对象
-
login({ commit }, form) {
-
console.log(commit);
-
api.post(
"/auth/login", form).then(
result => {
-
console.log(result);
-
commit(
"loginon", result);
-
});
-
},
-
//验证token
-
//commit提交mutation来改变当前的状态
-
checkedLogin({ commit, state }) {
-
//怎么传递请求头呢
-
api.defaults.headers.common[
"Token"] = state.info.token;
-
api.post(
"/auth/refreshToken").then(
(token) => {
-
console.log(token);
-
-
}).catch(
err => {
-
console.log(err);
-
})
-
console.log(commit);
-
-
}
-
}
在store文件夹下的index.js中去触发checkedLogin函数,通过store.dispatch方法
-
import Vue
from
'vue'
-
import Vuex
from
'vuex'
-
import user
from
'./modules/user'
-
import createPersistedState
from
'vuex-persistedstate'
-
Vue.use(Vuex)
-
-
export
default
new Vuex.Store({
-
-
modules: {
-
user
-
},
-
plugins: [
-
createPersistedState({
-
key:
"eStudy",
-
paths: [
"user"],
-
subscriber(store) {
-
store.dispatch(
"user/checkedLogin");
-
return
function(handler) {
-
return store.subscribe(handler);
-
}
-
}
-
})
-
]
-
})

如果验证成功了,我们可以看到token信息

如果成功应该续费,要更新token
想直接改变状态,要通过mutations去改变
在user.js中
先赋值,再调用
-
const mutations = {
-
loginon(state, data) {
-
state.login =
true;
-
state.info = data;
-
},
-
updateToken(state,token){
-
//赋值
-
state.info.token=token;
-
}
-
}
-
const actions = {
-
//context为环境对象
-
login({ commit }, form) {
-
console.log(commit);
-
api.post(
"/auth/login", form).then(
result => {
-
console.log(result);
-
commit(
"loginon", result);
-
});
-
},
-
//验证token
-
//commit提交mutation来改变当前的状态
-
checkedLogin({ commit, state }) {
-
console.log(commit);
-
//怎么传递请求头呢
-
api.defaults.headers.common[
"Token"] = state.info.token;
-
api.post(
"/auth/refreshToken").then(
(token) => {
-
console.log(token);
-
//调用
-
commit(
"updateToken",token);
-
-
}).catch(
err => {
-
console.log(err);
-
})
-
-
}
-
}
Token没过期保持登录,Token过期了的话,返回登录界面
1.先在action里面写,然后通过commit触发mutation里面的logout函数
-
const actions = {
-
-
logout({ commit }) {
-
commit(
"logout");
-
}
-
}
2.login为false返回登录界面
-
const mutations = {
-
-
logout(state) {
-
state.info = {};
-
state.login =
false;
-
}
-
}
3.这样还不行,需要在验证token的函数的token过期的回调函数中触发这个登出的函数,
通过传dispatch,并通过dispatch去触发登出的函数
-
const actions = {
-
//context为环境对象
-
login({ commit }, form) {
-
console.log(commit);
-
api.post(
"/auth/login", form).then(
result => {
-
console.log(result);
-
commit(
"loginon", result);
-
});
-
},
-
//验证token
-
//commit提交mutation来改变当前的状态
-
checkedLogin({ commit, state, dispatch }) {
-
console.log(commit);
-
//怎么传递请求头呢
-
api.defaults.headers.common[
"Token"] = state.info.token;
-
api.post(
"/auth/refreshToken").then(
(token) => {
-
console.log(token);
-
commit(
"updateToken", token);
-
-
}).catch(
err => {
-
console.log(err);
-
dispatch(
"logout");
-
})
-
-
},
-
logout({ commit }) {
-
commit(
"logout");
-
}
-
}
实现token过期,返回登录页面。
不想要请先登录这个提示信息
1.在登录的时候设置{ _slient: true }
-
checkedLogin({ commit, state, dispatch }) {
-
console.log(commit);
-
//怎么传递请求头呢
-
api.defaults.headers.common[
"Token"] = state.info.token;
-
api.post(
"/auth/refreshToken", {}, {
_slient:
true }).then(
(token) => {
-
console.log(token);
-
commit(
"updateToken", token);
-
-
}).catch(
err => {
-
console.log(err);
-
dispatch(
"logout");
-
})
-
-
}
2.我们在api.js中通过dir,测试一下
console.dir(error);

3.在拦截器中设置想要提示用户哪些内容,哪些不提示用户
-
//拦截器
-
api.interceptors.response.use(
response => {
-
return response.data.data;
-
}, error => {
-
console.dir(error);
-
const config = error.config;
-
const response = error.response;
-
if (!config._slient) {
-
Vue.$notification.error({
-
message:
"API Error",
-
description: response.data.errorMessage
-
});
-
}
-
-
return
Promise.reject(error);
-
})
转载:https://blog.csdn.net/weixin_42995083/article/details/106433313