【问题标题】:Guard for only one component under named view router - Vue js在命名视图路由器下仅保护一个组件 - Vue js
【发布时间】:2018-06-22 16:03:37
【问题描述】:

我有一个命名的视图路线:

let routes = [
    {
        name: "home",
        path: '/',
        components: {
            default: Home,
            project: ProjectIndex
        }
    }
]

我想根据用户角色保护“项目”路由,但任何人都可以访问默认主页。

我将这个添加到 ProjectIndex 组件中:

beforeRouteEnter (to, from, next) {

    var user = Spark.state.user;

    if(user.current_role == 'admin' || user.current_role == 'owner'){
        next();
    }

}

但路由器也在 Home 组件上执行此代码,因此 Home 也受此影响。

我不认为这么简单的事情在 Vue js 中应该这么难。

如果我console.log(to) 我得到了路线,但没有告诉我将呈现哪个组件。我在这里碰壁了。请帮忙。

【问题讨论】:

  • 对于任何寻找这个的人,答案是这些是“嵌套”命名视图,因此路由被视为相同,v-if 将条件渲染所以我的解决方案是使用 created()与 v-if 挂钩,您甚至可以使用 $router.push 重定向到另一条路由。

标签: javascript vue.js babeljs vue-router


【解决方案1】:

我将向您展示如何支持延迟加载。

//this function will do the check and import the component supporting lazy loading
//if the check does not fulfilled then the component will not imported 
function check_condition(name_component) {
    if (name_component === 'Project') { 
      const user = store.state.user

      if (user.current_role == 'admin' || user.current_role == 'owner') {
        return () => import(`@/components/${name_component}.vue`)
      }
      return
    }
    return () => import(`@/components/${name_component}.vue`)
}

export default new Router({
    routes: [
        {
            path: '/',
            name: 'home',
            components: {
                default: check_condition('Home'),
                project: check_condition('Project')
            }
        },
        {
            path: '/about',
            name: 'about',
            component: check_condition('About')
        }
    ]
})

我喜欢上面的方法。当然还有其他方法。 如果您不喜欢上述方法或它不适合您的问题,您可以尝试以下方法。

说你有是vuex store state:

state: { user: 'admin' //or visitor } 

并且您想在用户为admin 而不是visitor 时显示settings_button 组件:

computed: {
  should_show_settings_button () {
    return this.$store.state.user === 'admin'
  }
}

<template v-if="should_show_settings_button">
  <router-view name="settings_button"></router-view>
</template>

【讨论】:

  • 不错的方法:)。
  • 很高兴为您提供帮助:)
  • @DiegoPonciano 我为我的答案添加了另一种方法,您可以看看它。也许它更适合您的问题
【解决方案2】:

您可以简单地检查to url:

beforeRouteEnter (to, from, next) {
  if(to.pathname !== '/') {
      //yours check
  }
  else {
       next();
  }
}

或者更复杂的方法是每次检查您的路线数组。您可以通过组件名称进行检查。

let routesObjects = routes.reduce((obj, route) => { obj[route.path] = route.name; return obj; }, {});

beforeRouteEnter (to, from, next) {
    let path = to.pathname;
    if(routesObjects.hasOwnProperty(to) && routesObjects[to] !== 'home') {
        //yours check
    }
    else {
         next();
    }
}

如果您有 2 个具有相同 pathnam 的组件,您可以结合使用 beforeEach 钩子和 meta

在你的组件中设置meta标签

routes: [
    { name: 'home', path: '/', meta: { isHome: true } }
]

那就去看看吧

router.beforeEach((to, from, next) => {
  if(to.meta.isHome !== undefined && to.meta.isHome) { next(); }
  else { //your check  }
})

【讨论】:

  • 路由路径相同组件不同。
  • @DiegoPonciano 那么你应该使用另一个钩子。你不能访问beforeRouteEnter中的组件实例@
  • 那是我的困境用什么钩子?
  • 我应该使用created() 还是mounted()?不觉得那么干净:/
  • @DiegoPonciano 如何将beforeEachmeta 结合起来?
猜你喜欢
  • 2020-04-06
  • 2022-09-27
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 2018-01-07
  • 2019-09-29
  • 2017-07-31
  • 2021-12-29
相关资源
最近更新 更多