用 vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)

本文介绍如何使用Vue Router的beforeRouteUpdate方法实现导航守卫,包括登录验证等常见场景。通过示例展示了如何配置全局前置守卫以控制路由跳转。
路由跳转前做一些验证,比如登录验证(未登录去登录页),是网站中的普遍需求。对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫(navigation-guards)。
导航守卫(navigation-guards)这个名字,听起来怪怪的,但既然官方文档是这样翻译的,就姑且这么叫吧。
贴上文档地址:https://router.vuejs.org/zh-cn/advanced/navigation-guards.html

先来摘抄一段文档中beforeRouteUpdate 的用法:
你可以使用 router.beforeEach 注册一个全局前置守卫:
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
    • to: Route: 即将要进入的目标 路由对象

    • from: Route: 当前导航正要离开的路由

    • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

      • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

      • next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

      • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

      • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保要调用 next 方法,否则钩子就不会被 resolved。

下面写一个例子,上一篇博客中我们的账户页,包括课程和订单,都需要在跳转前判断是不是已登录; 已登录的情况再去登录页,跳转至首页:
const vueRouter = new Router({
    routes: [
        //......
        {
          path: '/account',
          name: 'account',
          component: Account,
          children: [
            {name: 'course', path: 'course', component: CourseList},
            {name: 'order', path: 'order', component: OrderList}
          ]
        }
    ]
});
vueRouter.beforeEach(function (to, from, next) {
    const nextRoute = [ 'account', 'order', 'course'];
    const auth = store.state.auth;
    //跳转至上述3个页面
    if (nextRoute.indexOf(to.name) >= 0) {
        //未登录
        if (!store.state.auth.IsLogin) {
            vueRouter.push({name: 'login'})
        }
    }
    //已登录的情况再去登录页,跳转至首页
    if (to.name === 'login') {
        if (auth.IsLogin) {
            vueRouter.push({name: 'home'});
        }
    }
    next();
});




<think> 我们被要求提供一个使用Element UI和Vue Router实现导航跳转路由的完整项目示例。根据引用内容,我们可以总结出关键点: 1. 在el-menu组件上设置`:router="true"`,这样菜单项被点击时会使用vue-router进行跳转。 2. 每个菜单项(el-menu-item)的index属性应该设置为路由的path(注意路径要以'/'开头,例如'/home')。 3. 设置default-active为当路由路径(this.$route.path),以确保当激活的菜单项与路由匹配。 此外,我们需要一个路由配置文件(router/index.js)来定义路由。 以下是一个完整的项目示例步骤: 步骤1:创建Vue项目并安装依赖 步骤2:配置路由 步骤3:创建页面组件 步骤4:在导航栏组件中使用Element UI的Menu组件,并配置路由跳转 详细代码: 1. 创建项目并安装依赖(假设已创建Vue项目): ```bash npm install element-ui vue-router --save ``` 2. 在src目录下创建router/index.js文件,配置路由: ```javascript import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home' import About from '@/views/About' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', component: About } ] }) ``` 3. 创建两个页面组件(在src/views目录下): - Home.vue ```vue <template> <div>首页</div> </template> ``` - About.vue ```vue <template> <div>关于我们</div> </template> ``` 4. 在App.vue(或某个布局组件)中,使用Element UI的Menu组件,并设置路由跳转: ```vue <template> <div id="app"> <el-menu :router="true" :default-active="$route.path" mode="horizontal" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"> <el-menu-item index="/">首页</el-menu-item> <el-menu-item index="/about">关于我们</el-menu-item> </el-menu> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> ``` 5. 在main.js中引入Element UI: ```javascript import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import App from './App.vue' import router from './router' Vue.use(ElementUI) new Vue({ router, render: h => h(App) }).$mount('#app') ``` 这样,当点击菜单项时,就会跳转到对应的路由,并且当激活的菜单项会高亮。 注意:如果路由有嵌套,或者需要更复杂的菜单结构(比如子菜单),可以使用el-submenu,并且同样设置index为路由路径。 引用说明: 根据引用[1]和引用[2]的内容,我们实现导航跳转的基本配置,包括设置`router`属性、index绑定路由路径、以及设置default-active为当路由路径。 相关问题: 1. 如何在Element UI导航菜单中处理嵌套路由? 2. 如何实现动态菜单(根据权限生成不同的菜单项)? 3.Vue2中使用Element UI菜单时,如何避免重复点击同一路由时的错误提示? 注意:由于用户要求完整的项目示例,以上代码已经能够构成一个最小可运行示例。用户可以根据需要扩展。 </think>以下是使用 Element UI 和 Vue Router 实现导航跳转路由的完整项目示例,结合引用内容和最佳实践: ### 项目结构 ```bash src/ ├── router │ └── index.js # 路由配置 ├── views/ # 页面组件 │ ├── Home.vue │ ├── Device.vue │ ├── Params.vue │ └── Picture.vue ├── components │ └── NavMenu.vue # 导航栏组件 └── App.vue ``` ### 核心代码实现 1. **路由配置 (`src/router/index.js`)** ```javascript import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home.vue' import Device from '@/views/Device.vue' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/device', // 注意:路径必须以/开头 name: 'Device', component: Device }, // 其他路由... ] }) ``` 2. **导航栏组件 (`src/components/NavMenu.vue`)** ```vue <template> <el-menu :router="true" :default-active="$route.path" mode="horizontal" > <el-menu-item index="/"> <i class="el-icon-s-home"></i> <span>首页</span> </el-menu-item> <el-menu-item index="/device"> <i class="el-icon-cpu"></i> <span>设备管理</span> </el-menu-item> <!-- 其他菜单项 --> </el-menu> </template> <script> export default { watch: { // 路由变化时更新激活菜单 '$route'(to) { this.$nextTick(() => { this.$refs.menu.activeIndex = to.path }) } } } </script> ``` 3. **主应用入口 (`src/App.vue`)** ```vue <template> <div id="app"> <NavMenu /> <router-view class="main-content"/> </div> </template> <script> import NavMenu from '@/components/NavMenu.vue' export default { components: { NavMenu } } </script> ``` ### 关键配置说明(引用[1][^1]) 1. **`:router="true"`** 启用 Vue Router 集成模式,使菜单点击触发路由跳转 2. **`index` 属性** 必须设置为完整路由路径(含开头的`/`),如: ```html <el-menu-item index="/device">设备管理</el-menu-item> ``` 3. **`default-active`** 绑定 `$route.path` 实现路由变化时自动更新激活状态: ```html :default-active="$route.path" ``` ### 完整流程演示 ```mermaid graph TD A[用户点击导航菜单] --> B[Menu组件index属性] B --> C[匹配router/index.js中的path] C --> D[加载对应组件] D --> E[RouterView渲染组件] E --> F[更新$route.path] F --> G[Menu高亮当项] ``` ### 常见问题解决方案 1. **菜单不高亮** 确保 `default-active` 绑定的是 `$route.path` 而非 `$route.name` 2. **路由跳转失败** 检查路由配置中的 `path` 是否以 `/` 开头(引用[2][^2]) 3. **嵌套路由处理** 使用 `el-submenu` 实现多级菜单: ```vue <el-submenu index="/system"> <template #title>系统管理</template> <el-menu-item index="/system/users">用户管理</el-menu-item> <el-menu-item index="/system/roles">角色管理</el-menu-item> </el-submenu> ``` > 实际项目示例: > [GitHub - vue2-element-admin](https://github.com/PanJiaChen/vue-element-admin)(企业级实践) > [Gitee - vue2-element-tpl](https://gitee.com/mirrors/vue-admin-template)(精简模板)
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值