一、初始化项目
1. 复制 vue 工程为 sms-vuex
2. 安 装 Vuex
# 进入工程目录
cd sms-vuex
# 安装依赖
npm install --save vuex
# 启动项目npm run serve
二、登录
1.登录与 token 状态管理
1.1.在 src\utils\ 目录下创建 auth.js, 封装 token 和 用户信息工具模块
let tonke_key = "sms-token"
let user_key = "sms-user"
// 拿到token
export function getToken() {
return localStorage.getItem(tonke_key)
}
// 设置token
export function setToken(token) {
return localStorage.setItem(tonke_key, token)
}
// 拿到 用户信息
export function getUser() {
// return JSON.parse(localStorage.getItem(user_key))
return localStorage.getItem(user_key)
}
// 设置用户信息
export function setUser(user) {
console.log(user);
return localStorage.setItem(user_key, JSON.stringify(user))
}
// 移出用户信息
export function removeUser() {
localStorage.removeItem(tonke_key)
localStorage.removeItem(user_key)
}
1.2. 在 src 目录下新建 store\modules 目录,modules 下创建 user.js
import { getToken, setToken, getUser, setUser, removeUser } from "../../utils/auth";
export default {
state: {
token: null,
user: null
},
mutations: { //set_token方法
set_token(state, token) {
state.token = token
setToken(token)
},
},
actions: {
}
}
1.3. 在 src\store 目录下创建 index.js
import Vue from "vue"
import Vuex from "vuex"
import user from "./modules/user.js"
Vue.use(Vuex)
export default new Vuex.Store({
modules:{
user
}
})
1.4. 修改 src 下的 main.js,导入和注册 store
import store from "./store"
new Vue({
router,
store,
render: (h) => h(App), //渲染数据
}).$mount("#app");
1.5. 重构登录组件 views\login\index.vue
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
login(this.form.username, this.form.password)
.then((res) => {
let resArr=res.data
if (resArr.flag) {
//这里代表真正登录进来了
info(resArr.data.token)
.then((res) => {
if (res.data.flag) {
localStorage.setItem(
"sms-user",
JSON.stringify(res.data.data)
);
// localStorage.setItem(
// "sms-token",
// resArr.data.token
// );
this.$store.commit("set_token",resArr.data.token)
this.$router.push('/')
}
})
.catch((err) => {
console.log("错误");
});
}
})
.catch((err) => {
console.log("err", err);
});
}else {
return false;
}
});
},
},
1.6. 测试登录是否正常进入,并观察浏览器中localStorage是否有值
1.7把登录写出来:
import { getToken, setToken, getUser, setUser, removeUser } from "../../utils/auth";
import { login, getUserInfo, logout } from "../../api/login";
export default {
namespaced: true,
state: {
token: getToken(),
user: getUser()
},
mutations: { //set_token
set_token(state, token) {
state.token = token
setToken(token)
},
},
actions: {
Login({ commit }, form) {
return new Promise((resolve, reject) => {
login(form.username, form.password).then(res => {
let resArr = res.data
commit("set_token", resArr.data.token)
resolve(resArr)
}).catch(err => {
reject(err)
})
})
},
}
}
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$store.dispatch('user/Login', this.form)
this.$router.push("/");
} else {
return false;
}
});
},
},
在router的index.js中:
import Vue from "vue";
import VueRouter from "vue-router";
import Register from "../views/register/index.vue";
import login from "../views/login/index.vue"
import layout from "../components/layout.vue"
import home from "../views/home/index.vue"
import teacher from "../views/teacher/index.vue"
import students from "../views/students/index.vue"
import { getUserInfo } from "@/api/login.js"
import store from "../store";
Vue.use(VueRouter);
const routes = [{
path: "/register",
name: "register",
component: Register,
}, {
path: "/login",
name: "login",
component: login,
}, {
path: "/",
name: "layout",
component: layout,
redirect: "/home",
children: [{ path: "/home", meta: { title: "首页" }, component: home }]
},
{
path: "/teacher",
name: "teacher",
component: layout,
children: [{
path: "/",
name: "teacher",
meta: { title: "老师管理" },
component: teacher,
}]
},
{
path: "/students",
name: "students",
component: layout,
children: [{
path: "/",
meta: { title: "学生管理" },
component: students,
}]
},
];
const router = new VueRouter({
routes,
});
router.beforeEach((to, from, next) => {
let tonken = store.state.user.token
if (!tonken) {
if (to.path == "/login") {
next()
} else if (to.path == "/register") {
next()
} else {
next({ path: '/login' })
}
} else {
if (to.path == "/login") {
next()
} else if (to.path == "/register") {
next()
} else {
let userinfo = store.state.user.user
// console.log(userinfo);
// if (userinfo) {
// next()
// } else {
store.dispatch("user/GetUser").then(res => {
if (res.flag) {
// console.log(userinfo,res);
next()
} else {
next({ path: '/login' })
}
}).catch(err => {
console.log(err);
})
// }
}
}
})
export default router;
2.获取用户信息
之前获取用户信息是在登录中一起获取的,其实可以在权限拦截器( permission.js )中进行获取就行。
2.1. 修改 src\store\modules\user.js, 在 actions 中添加 GetUser方法
GetUser({ commit, state }) {
return new Promise((res, rej) => {
getUserInfo(state.token).then(response => {
let resArr = response.data
commit("set_user", resArr.data)
res(resArr)
}).catch(err => {
rej(err)
})
})
},
3.退出
3.1.修改src\store\modules\user.js,在actions中添加Logout方法
Logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(res => {
let resArr = res.data
commit("set_token", "")
commit("set_user", null)
removeUser()
resolve(resArr)
}).catch(err => {
reject(err)
})
})
}
3.2. 修改 src\components\AppHeader\index.vue 头部组件,把out():
out() {//退出登录
// logout(localStorage.getItem("sms-token"))
// .then((res) => {
// let resArr = res.data;
// if (resArr.flag) {
// // 清除本地数据
// localStorage.removeItem("sms-token");
// localStorage.removeItem("sms-user");
// this.$router.push("/login"); //退出登录,让它回到登录页面
// }
// })
// .catch((err) => {
// console.log("err", err);
// });
this.$store.dispatch('user/Logout').then(res=>{
if(res.flag){
this.$router.push("/login"); //退出登录,让它回到登录页面
}
})
},
3.3. 测试 右上角显示名字正常, 退出正常