vuex项目中登录状态管理的实践过程
目录
- 工具:
- 登录场景:
- 实践:
- 场景1思考与实践
- 场景2思考与实践
- 总结
工具:
chorme浏览器安装Vue.js devtools方便调试
登录场景:
页面的导航处或其他地方有时会显示用户现在的登录状态,状态可分为:未登录,正在登录(loading),登录成功并显示用户名。
有些页面是不需要登录就可以让用户浏览的,但是有些页面必须登录才可以进入浏览。
实践:
场景1思考与实践
用vuex创建一个数据仓库
//src目录下新建一个store目录,创建index.js如下 //创建数据仓库 import Vuex from 'vuex'; import vue from 'vue'; import loginUser from 'loginUser.js' Vue.use(Vuex) const store = new Vuex.Store({ modules: { //modules 可以把不同的状态单独的放在一个对象里面 loginUser //是否正在登录中 }, strict: true, //只允许通过mutations改变状态 });
设置登录状态loading和当前登录用户user
//创建一个loginUser.js,创建他的state/mutations/actions //需要维护的状态 state: { loading: false, //登录状态 user: null, //当前登录的用户 }, //计算属性 getters: { status(state) { if (state.loading) { return 'loading' } else if (state.user) { return 'login' } else { return 'unLogin' } } }, //改变loading和user状态 mutations: { //设置loading setLoading(state, msg) { state.loading = msg }, //设置用户 setUser(state, msg) { state.user = msg } }, //actions中提交改变的状态 actions: { //登陆方法ctx相当于store async login(ctx, msg) { //登陆状态设置为true ctx.commit("setLoading", true) const result = await xxxapi.login(msg.loginId, msg.loginPassword) if (result) { //登录成功 ctx.commit('setUser', result) bgp服务器http://www.558idc.com/yz.html //登陆成功后登陆状态设置为false ctx.commit('setLoading', false) } //返回登陆是否成功 return result }, //判断是否已登录 async isLogin(ctx) { //正在登录中 ctx.commit('setLoading', true) //调接口是否登陆 const result = await xxxapi.isLogin(); ctx.commit('setUser', result); ctx.commit('setLoading', false) }, //注销 async logout(ctx) { ctx.commit('setLoading', false) await xxxapi.logout(); ctx.commit('setUser', null); ctx.commit('setLoading', false) } },
页面使用:
在登录时,有一个登录按钮,按钮的状态我们就可以在Vuex的仓库中获取
<button :disabled="loading">{{ loading ? 'loading...' : '登录' }} </button> computed: { //在computed中封装一下loading,不用每次调用都写this.$store.state.loginUser这一堆 // loading() { // return this.$store.state.loginUser.loading; // } // 优化 //辅助函数 //import {mapState} from "vuex" ...mapState({ loading: (state) => state.loginUser.loading }) }
点击按钮的时候提交的时候分发action
async handleSubmit() { const result = await this.$store.dispatch("loginUser/login", { loginId: this.loginId, loginPassword: this.loginPassword }); if (result) { // 登录成功 路由跳转 const path = this.$route.query.url || '/' this.$router.push(path) } },
页面的导航中切换显示此时的登录状态[loading/login/unlogin]
<!-- 显示页面登录状态--> <span v-if="status === 'loading'">正在登录请稍等...</span> <template v-else-if="status === 'login'"> <span>当前登录用户{{user.name}}</span> <span @click="handleLogout">退出</span> </template> <router-link to="/login" v-else> 登录 </router-link> computed: { ...mapGetters("loginUser", ["status"]), ...mapState("loginUser", ["user"]), }
登出时 更改状态
async handleLogout(){ await this.$store.dispatch("loginUser/logout") //跳转到登陆页面 this.$route.push(/xxx) }, 每次页面刷新需要检测登录状态,在main.js中,也就是vue创建的时候就要判断。 store.dispatch('loginUser/isLogin')
场景2思考与实践
参考了后台项目中的权限设置
总体设计:
刷新页面后,在Vuex仓库中先检测此时登录状态–> 导航守卫(router.beforeEach)通过判断meta中设置的参数检测此页面是否
需要登录后才能查看 -->页面渲染。
整体逻辑:
1.进入页面时判断此页面是否需要登录才能查看
2.判断登录状态。有三种状态如下:
- 如果已经登录了就直接进入想去的页面。
- 如果没登录,就进入登录页面让用户登录。
- 如果状态是加载中(loading),要传入想去的页面的路径,并在加载中页面监控Vuex仓库中用户登录状态的变化,监听状态变化完了之后,此时要不就是已经登录了,要不就是没有登录的状态,然后再走第1步判断是否要登录权限。
实践:
在router中设置meta,如果auth为true就是需要登录才能访问
//routes.js中 import Home from "./xx/xx.vue" export default[ { path:"/home", component:Home, meta: { auth: true, //需要权限才可以访问的页面 } } ] 在index.js中设置路由守卫 router.beforeEach((to, from, next) => { if (to.meta.auth) { // 需要登录权限才可以访问 const result = store.getters["loginUser/status"] if (result === 'loading') { // 加载状态,不知道有没有登录 // 跳转一个正在登录中页面,并且要在页面中监控是否已经登录成功了,要不然会永远停留在这里 // 并且路由跳转的时候得记录你之前是从哪里过来的,要不然不知道要跳转到哪一个页面 next({ path: '/loading', //去【正在登录中】的页面 query: { url: to.fullpath } }) } else if (result === 'login') { // 登录成功了 next(); } else { // 没有登录 this.$message.info('你需要登录'); next({ path: '/login', //去【正在登录中】的页面 query: { url: to.fullpath } }) } } else { //不需要登录权限就可以访问的页面 next() } })
在logining【正在登录中】页面中监控此时的状态
created() { this.unWatch = this.$watch(() => this.$store.getters["loginUser/status"], (status) => { console.log('此时的状态', status); if (status !== 'loading'){ this.$router.push(this.$route.query.url || '/home').catch(() => {} } }, { immediate: true }) }, destroyed() { //取消监控 this.unWatch() }
总结
到此这篇关于vuex项目中登录状态管理的文章就介绍到这了,更多相关vuex登录状态管理内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!