vuex实现项目中登录状态的管理

工具:
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)
               //登陆成功后登陆状态设置为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. 场景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()
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
项目使用Vuex有以下几个好处: 1. 集状态管理Vuex提供了一个集式的状态管理方案,将数据存储在一个单一的store。这使得不同组件之间共享和访问数据变得简单和直观。无论在项目的哪个组件,都可以轻松地获取和修改共享的状态。 2. 组件间通信:Vuex提供了一种可预测的状态管理机制,可以在不同的组件之间进行通信和共享数据。通过定义和触发mutations来修改状态,各个组件都可以监听状态的变化并作出相应的反应,实现了组件之间的解耦。 3. 状态持久化:Vuex支持对状态进行持久化存储,可以通过插件将状态保存到本地存储或其他持久化方式。这样,在页面刷新或重新加载后,可以恢复之前的状态,提供更好的用户体验。 4. 易于调试和追踪:Vuex提供了强大的开发者工具支持,可以方便地进行状态的调试、追踪和回溯。开发者可以轻松地查看状态的变化历史、调试mutation的执行过程等,帮助快速定位和解决问题。 5. 插件扩展:Vuex提供了丰富的插件机制,可以通过插件扩展Vuex的功能。开发者可以编写自定义插件来实现特定的需求,例如数据持久化、日志记录、异步操作等。 总的来说,Vuex通过集状态管理、组件间通信、状态持久化、调试追踪等特性,使得状态管理变得更加简单和可预测。它为大型项目提供了一种可靠的状态管理解决方案,提高了开发效率和代码的可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值