【问题标题】:Vue router navigation gaurd from within the component组件内部的 Vue 路由器导航栏
【发布时间】:2017-08-09 00:36:19
【问题描述】:

我使用集中状态管理的 vuex 在我的 vuex store.js 中,我将登录状态存储为布尔值,如下所示

export const store = new Vuex.Store({
state: {
loggedIn: false,
userName: 'Guest',
error: {
    is: false,
    errorMessage: ''
}
},
getters: {
g_loginStatus: state => {
    return state.loggedIn;
},
g_userName: state => {
    return state.userName;
},
g_error: state => {
    return state.error;
}
}
)};

当用户登录时,我将 loginstatus 设置为 true 并删除登录按钮并将其替换为注销按钮 一切正常,但问题是当用户登录时,如果我直接在搜索栏中输入登录组件的路径,我可以再次导航到登录页面 我想展示这种行为 如果用户已登录并在搜索栏中搜索登录页面的路径,则必须将其重定向到主页

我尝试在登录组件中使用 beforeRouteEnter 但我们无法访问 this 实例,因为组件尚未加载 那么如何从我的商店检查登录状态

我在 login.vue 中的脚本

script>

export default{
    data(){
        return{
            email: '',
            password: ''
        };
    },
    methods: {
        loginUser(){
            this.$store.dispatch('a_logInUser', {e: this.email, p: this.password}).then(() =>{
                this.$router.replace('/statuses');

            });
        }
    },
    beforeRouteEnter (to, from, next) {
        next(vm => {
            if(vm.$store.getters.g_loginStatus === true){
                 //what shall i do here
            }
        })
    }
}

【问题讨论】:

    标签: vue.js vuejs2 vue-router vuex


    【解决方案1】:

    最好将导航守卫放在路由而不是页面/组件中,并在路由文件中调用状态获取器。

    // /router/index.js
    
    import Vue from 'vue'
    import Router from 'vue-router'
    import store from '../store'
    
    // Protected Pages
    import Dashboard from '@/views/dashboard'
    
    // Public Pages
    import Dashboard from '@/views/login'
    
    Vue.use(Router)
    
    // If you are not logged-in you will be redirected to login page
    const ifNotAuthenticated = (to, from, next) => {
      if (!store.getters.loggedIn) {
        next()
        return
      }
      next('/') // home or dashboard
    }
    
    // If you are logged-in/authenticated you will be redirected to home/dashboard page    
    const ifAuthenticated = (to, from, next) => {
      if (store.getters.loggedIn) {
        next()
        return
      }
      next('/login')
    }
    
    const router = new Router({
      mode: 'history',
      linkActiveClass: 'open active',
      scrollBehavior: () => ({ y: 0 }),
      routes: [
        {
          path: '/',
          redirect: '/dashboard',
          name: 'Home',
          component: Full,
          children: [
            {
              path: 'dashboard',
              name: 'Dashboard',
              component: Dashboard,
              beforeEnter: ifAuthenticated
            },
          ]
        },
        {
          path: '/login',
          name: 'Login',
          component: Login,
          beforeEnter: ifNotAuthenticated
        },
        {
          path: '*',
          name: 'NotFound',
          component: NotFound
        }
      ]
    })
    
    export default router
    

    也可以使用 vue-router-sync 包获取 store values 的值

    【讨论】:

      【解决方案2】:

      您可以将用户重定向到主页或其他相关页面:

      mounted () {
              if(vm.$store.getters.g_loginStatus === true){
                   this.$router('/')
              }
      }
      beforeRouteEnter (to, from, next) {
          next(vm => {
              if(vm.$store.getters.g_loginStatus === true){
                   next('/')
              }
          })
      }
      

      来自docs

      next: 函数:必须调用这个函数来解决钩子。该操作取决于提供给 next 的参数:

      • next():移动到管道中的下一个钩子。如果没有留下任何钩子,则确认导航。

      • next(false):中止当前导航。如果浏览器 URL 被更改(由用户手动或通过后退按钮),它将被重置为 from 路由。

      • next('/') 或 next({ path: '/' }):重定向到不同的位置。当前导航将中止并开始新的导航。

      【讨论】:

      • 我已经尝试过这种方法,,,,有时它有效,但有时如果我直接在搜索中输入登录页面 url,登录页面就会打开。
      • @VamsiKrishna 试试我编辑的代码,添加挂载块。
      • 尝试添加挂载的钩子,但现在我按下登录按钮后没有任何反应,当我点击其他路由器链接时 url 发生变化,但页面停留在登录页面上
      • 我什至尝试将登录状态动态传递给参数然后在我的 beforeRouteEnter 中我使用条件 if(to.params.status === true) 重定向到主页,,, 但是现在当我重新启动应用程序登录页面组件未显示
      猜你喜欢
      • 2021-09-20
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 2019-02-21
      • 2020-10-27
      • 2021-08-24
      相关资源
      最近更新 更多