当前位置: 首页 > news >正文

科技公司网站欣赏长沙软件培训机构排名前十

科技公司网站欣赏,长沙软件培训机构排名前十,河北邢台特色美食,网站没备案可以访问吗一、导航守卫基础认知 1.1 核心定义与作用 导航守卫是 Vue Router 提供的路由跳转拦截与控制机制,可在路由“跳转前、跳转中、跳转后”插入自定义逻辑,实现权限验证、数据预加载、导航拦截等核心需求。 类比理解:如同“城门守卫”——所有路由…

一、导航守卫基础认知

1.1 核心定义与作用

导航守卫是 Vue Router 提供的路由跳转拦截与控制机制,可在路由“跳转前、跳转中、跳转后”插入自定义逻辑,实现权限验证、数据预加载、导航拦截等核心需求。
类比理解:如同“城门守卫”——所有路由跳转需经过守卫检查,符合条件则“放行”,不符合则“拦截”或“重定向”。

1.2 核心特性

  • 拦截时机全覆盖:覆盖导航全生命周期(前/中/后),适配不同业务场景。
  • 作用范围灵活:支持“全局(所有路由)、局部(特定路由/组件)”,兼顾通用性与针对性。
  • 控制能力强:可直接决定导航结果(放⾏/拦截/重定向),并获取路由上下文信息(目标/来源路由)。

二、全局导航守卫(影响所有路由)

全局导航守卫是项目级别的拦截逻辑,任何路由跳转都会触发,核心包括三类:全局前置守卫、全局解析守卫、全局后置钩子。其中全局前置守卫是实战中最常用的类型。

2.1 全局前置守卫(router.beforeEach

全局前置守卫是“路由跳转前的第一道关卡”,常用于登录验证、权限控制等核心场景,必须调用 next() 函数才能完成导航,否则路由会被永久阻塞。

1. 基础用法(注册与参数)
(1)规范注册流程(企业级实践)

为避免代码臃肿,需单独创建 router/guard.js 文件(符合“单一职责原则”),步骤如下:

// 1. 新建 router/guard.js(守卫专用文件)
import router from './index' // 关键:先创建路由实例,再注册守卫// 2. 注册全局前置守卫
router.beforeEach((to, from, next) => {// to:即将进入的目标路由对象(含 path、name、params、query 等)// from:当前正要离开的路由对象(来源路由信息)// next:必须调用的“导航解析函数”,控制导航结果console.log(`${from.path} 跳转到 ${to.path}`)// 业务逻辑后必须调用 next()next() // 无参 = 无条件放⾏
})// 3. 在 main.js 中引入守卫文件(确保执行顺序:Vue → Router → 路由实例 → 守卫)
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './router/guard' // 仅需执行注册,无需接收返回值new Vue({router,render: h => h(App)
}).$mount('#app')
(2)next() 函数详解(核心!)

next() 是控制导航的关键,不同调用方式对应不同行为,需严格区分:

next() 调用方式作用与适用场景
next()无条件放⾏,进入下一个导航钩子(正常流程,如已登录用户访问首页)
next(false)中断当前导航,URL 重置为 from 路由地址(如阻止未登录用户访问敏感页)
next('/path')next({ name: 'RouteName' })重定向到指定路由,中断原导航(如未登录时跳转到登录页)
next(error)传入 Error 实例,终止导航并触发 router.onError() 回调(用于错误监控与提示)
2. 实战场景:登录验证(含白名单防死循环)

未登录用户仅能访问登录页,已登录用户可自由访问——这是最典型的全局前置守卫场景,必须添加白名单(避免跳转登录页时再次触发守卫,导致死循环)。

// router/guard.js
import router from './index'// 1. 模拟登录状态(实际项目中从 localStorage/cookie 读取 token)
const isLogin = () => {return localStorage.getItem('token') !== null // token 存在 = 已登录
}// 2. 白名单:无需登录即可访问的路由(必须包含登录页)
const whiteList = ['/login']// 3. 登录验证逻辑
router.beforeEach((to, from, next) => {if (isLogin()) {// 已登录:若目标是登录页,重定向到首页(避免重复登录)to.path === '/login' ? next('/home') : next()} else {// 未登录:若目标在白名单内,放⾏;否则重定向到登录页whiteList.includes(to.path) ? next() : next('/login')}
})
3. 常见问题与排查
错误现象原因分析解决方案
路由被阻塞,页面空白未调用 next() 函数,导航无法完成确保所有分支逻辑中都有 next() 调用
死循环(Maximum call stack size exceeded)未加白名单,重定向路由(如登录页)再次触发守卫新增白名单,包含无需验证的路由(如 /login
router 实例未定义守卫注册早于路由实例创建先执行 new VueRouter(),再引入守卫文件

2.2 全局解析守卫(router.beforeResolve

全局解析守卫与前置守卫功能类似,但执行时机更晚:在“所有组件内守卫和异步路由组件解析完成后”触发,确保路由跳转前所有依赖已准备就绪。

// router/guard.js
router.beforeResolve((to, from, next) => {console.log('所有组件内守卫与异步组件已解析')next() // 仍需调用 next() 放⾏
})

应用场景:需等待异步数据加载完成后再跳转(如获取用户权限信息后决定是否放⾏),实际开发中使用频率低于前置守卫。

2.3 全局后置钩子(router.afterEach

全局后置钩子是“路由跳转完成后”的回调,next() 函数,仅用于监听导航结果(无法控制导航行为),类比“导航后的收尾工作”。

1. 基础用法
// router/guard.js
router.afterEach((to, from) => {// 仅接收 to(目标)和 from(来源)参数,无 next()console.log(`导航完成:从 ${from.path}${to.path}`)// 典型场景:// 1. 页面访问统计(上报用户行为)// reportAnalytics(to.path, from.path)// 2. 关闭全局 loading 状态// store.commit('closeGlobalLoading')// 3. 重置页面滚动位置(避免跳转后停留在原位置)window.scrollTo(0, 0)
})
2. 与“守卫”的核心区别
对比维度守卫(如 beforeEach钩子(如 afterEach
执行时机导航过程中(跳转前/中)导航完成后(跳转后)
控制能力可控制导航(放⾏/拦截/重定向)无控制能力,仅执行回调
参数差异接收 tofromnext 三个参数仅接收 tofrom 两个参数

三、路由独享守卫(仅影响特定路由)

路由独享守卫是“绑定在单个路由上的拦截逻辑”,仅当访问该路由时触发,适合保护敏感页面(如财务模块、管理员页面),避免全局守卫的“无差别拦截”,提升性能。

3.1 基础用法(配置与参数)

在路由配置对象中通过 beforeEnter 属性定义,参数与全局前置守卫一致(tofromnext)。

// router/index.js
const routes = [{path: '/home',name: 'Home',component: () => import('@/views/Home.vue')},// 路由独享守卫:仅访问 /finance(财务页)时触发{path: '/finance',name: 'Finance',component: () => import('@/views/Finance.vue'),beforeEnter: (to, from, next) => {// 业务逻辑:仅管理员可访问财务页const userRole = localStorage.getItem('role')if (userRole === 'admin') {next() // 管理员:放⾏} else {next('/403') // 非管理员:跳转 403 无权限页}}},{path: '/403',component: () => import('@/views/Forbidden.vue') // 403 组件}
]

3.2 与全局守卫的区别

对比维度全局前置守卫(beforeEach路由独享守卫(beforeEnter
作用范围所有路由跳转仅配置该守卫的特定路由
执行时机所有路由跳转前访问特定路由前
性能优势可能存在无效拦截(如普通页面也触发)仅拦截敏感路由,减少不必要判断
死循环风险高(需白名单)低(仅影响单个路由,不会反复触发)

四、组件内守卫(绑定在组件上)

组件内守卫是“绑定在 Vue 组件上的路由拦截逻辑”,仅当组件与路由关联时触发(如进入/离开该组件对应的路由),适合组件级别的权限控制或数据预加载。

4.1 三种组件内守卫对比

守卫类型执行时机能否访问 this核心场景
beforeRouteEnter路由进入组件前(组件未创建)❌ 不能组件渲染前预加载数据、组件级权限验证
beforeRouteUpdate路由变化但组件复用(如 /user/1/user/2✅ 能动态路由参数变化时更新数据(避免组件重建)
beforeRouteLeave路由离开组件前(组件已存在)✅ 能阻止未保存表单的意外离开、清理组件状态

4.2 实战示例

1. beforeRouteEnter:预加载数据(无 this 处理)

因组件未创建,无法直接访问 this,需通过 next() 的回调函数获取组件实例。

<!-- src/views/UserDetail.vue(用户详情页) -->
<template><div><h1>用户详情</h1><p>用户名:{{ user.name }}</p><p>用户ID:{{ user.id }}</p></div>
</template>
<script>
export default {name: 'UserDetail',data() {return {user: {} // 存储预加载的用户数据}},// 组件内守卫:进入路由前预加载数据beforeRouteEnter(to, from, next) {// 1. 模拟异步请求(实际项目中调用接口)const fetchUser = () => {return new Promise(resolve => {setTimeout(() => {// 从路由参数(to.params)获取用户IDresolve({ id: to.params.id, name: '张三' })}, 500)})}// 2. 预加载完成后,通过 next 回调注入组件实例fetchUser().then(userData => {next(vm => {// vm 等同于组件实例(this)vm.user = userData})})}
}
</script>
2. beforeRouteLeave:阻止未保存表单离开

用户编辑表单未提交时,离开路由会弹出确认框,避免数据丢失。

<!-- src/views/EditForm.vue(编辑表单页) -->
<template><div><textarea v-model="form.content" placeholder="请输入内容" style="width: 300px; height: 100px;"></textarea><button @click="submitForm" style="margin-top: 10px;">提交表单</button></div>
</template>
<script>
export default {name: 'EditForm',data() {return {form: { content: '' },isSaved: false // 标记表单是否已提交}},methods: {submitForm() {// 模拟表单提交console.log('表单提交:', this.form.content)this.isSaved = truethis.$router.push('/home') // 提交后跳转到首页}},// 组件内守卫:离开路由前检查表单状态beforeRouteLeave(to, from, next) {if (!this.isSaved && this.form.content.trim()) {// 未保存且有内容:弹出确认框const isConfirm = window.confirm('表单未提交,确定离开吗?')isConfirm ? next() : next(false) // 确认则放⾏,否则中断} else {next() // 已保存或无内容:直接放⾏}}
}
</script>

五、补充重点知识(面试与实战必备)

5.1 导航守卫的执行顺序(面试高频)

当触发路由跳转时,各类守卫的执行顺序严格遵循“从全局到局部、从跳转前到跳转后”:

  1. 触发全局前置守卫beforeEach);
  2. 触发目标路由的独享守卫beforeEnter);
  3. 触发**目标组件的 **beforeRouteEnter
  4. 触发全局解析守卫beforeResolve);
  5. 导航确认,组件渲染;
  6. 触发全局后置钩子afterEach);
  7. 触发目标组件的 mounted 生命周期。

实战小练习

6.1 题目

  1. 全局前置守卫实战:实现“多角色权限控制”,要求:
    • 普通用户(role: 'user'):可访问 /home/profile/login
    • 管理员(role: 'admin'):可访问所有路由(含 /admin/finance);
    • 未登录用户:仅可访问 /login,否则跳转登录页;
    • 无权限用户:跳转 /403 无权限页(需创建 Forbidden.vue 组件)。
  2. 路由独享守卫实战:双重保护 /finance 路由,要求:
    • 即使全局守卫失效,仅管理员可访问 /finance,普通用户跳转 /403(双重保险)。
  3. 组件内守卫实战:优化“编辑表单”组件,要求:
    • 表单内容变化后(未提交),离开路由时弹出确认框;
    • 表单提交后,允许直接离开,且跳转时清空表单内容。
  4. 全局后置钩子实战:实现“页面访问统计与滚动重置”,要求:
    • 每次路由跳转后,在控制台打印“[时间] 用户从 [来源路径] 跳转到 [目标路径]”;
    • 自动重置页面滚动位置到顶部(平滑滚动)。

6.2 参考答案

1. 全局前置守卫:多角色权限控制
(1)创建 403 组件(Forbidden.vue
<template><div style="text-align: center; margin-top: 50px; color: #f44336;"><h1>403 - 无访问权限</h1><router-link to="/home" style="color: #2196f3; margin-top: 20px; display: inline-block;">返回首页</router-link></div>
</template>
(2)配置守卫逻辑(router/guard.js
import router from './index'// 1. 角色-路由权限映射(key:角色,value:可访问路由列表)
const roleRouteMap = {user: ['/home', '/profile', '/login'],admin: ['/home', '/profile', '/admin', '/finance', '/login']
}// 2. 白名单:未登录用户可访问的路由
const whiteList = ['/login']// 3. 权限控制逻辑
router.beforeEach((to, from, next) => {const token = localStorage.getItem('token') // 登录标识const role = localStorage.getItem('role') || 'user' // 默认普通用户if (!token) {// 未登录:仅白名单路由放⾏whiteList.includes(to.path) ? next() : next('/login')} else {// 已登录:检查角色权限const allowRoutes = roleRouteMap[role]if (allowRoutes.includes(to.path)) {next() // 有权限:放⾏} else {next('/403') // 无权限:跳转 403 页}}
})
2. 路由独享守卫:保护 /finance 路由
// router/index.js
const routes = [{path: '/finance',name: 'Finance',component: () => import('@/views/Finance.vue'),// 路由独享守卫:双重验证管理员权限beforeEnter: (to, from, next) => {const role = localStorage.getItem('role')role === 'admin' ? next() : next('/403')}}
]
3. 组件内守卫:编辑表单离开确认
<!-- src/views/EditForm.vue -->
<template><div><textarea v-model="form.content" placeholder="请输入内容" @input="markChanged"style="width: 300px; height: 100px;"></textarea><button @click="submitForm" style="margin-top: 10px;">提交表单</button></div>
</template>
<script>
export default {name: 'EditForm',data() {return {form: { content: '' },isSaved: false, // 标记是否提交isChanged: false // 标记内容是否变化}},methods: {markChanged() {this.isChanged = true // 内容变化时更新标记},submitForm() {// 模拟提交逻辑console.log('表单提交:', this.form.content)this.isSaved = truethis.form.content = '' // 提交后清空表单this.$router.push('/home') // 跳转到首页}},// 组件内守卫:离开前检查状态beforeRouteLeave(to, from, next) {if (this.isChanged && !this.isSaved) {const isConfirm = window.confirm('内容已修改但未提交,确定离开吗?')isConfirm ? next() : next(false)} else {next()}}
}
</script>
4. 全局后置钩子:访问统计与滚动重置
// router/guard.js
router.afterEach((to, from) => {// 1. 页面访问统计(格式:[时间] 用户从 来源 跳转到 目标)const time = new Date().toLocaleString()console.log(`[${time}] 用户从 ${from.path} 跳转到 ${to.path}`)// 2. 平滑重置滚动位置到顶部window.scrollTo({top: 0,behavior: 'smooth' // 平滑滚动(可选,移除则为瞬间跳转)})
})
http://www.dtcms.com/a/405547.html

相关文章:

  • 3g 手机网站建设网站知识架构
  • 南京电信网站备案企业所得税的优惠政策
  • 钓鱼网站实施过程做标签这个网站刷单安全吗
  • 莒县做网站网站图片移动怎么做的
  • 有专业做外贸的网站吗勒索做钓鱼网站的人
  • win8扁平化网站云南云南住房和城乡建设厅网站
  • 农机网站建设目标网站开发字体选择
  • 长沙网页制作公司太原seo软件
  • 网站设计建设步骤wordpress asp
  • 网站备案号要怎么查询如何开电商店铺
  • 网站客户案例怎么恶意点击对手竞价
  • 沈阳网站选禾钻科技模板形的网站制作
  • 响应式网站制作流程用手机免费制作app软件下载
  • 网站备案完毕 怎样建设网站网站开发需要什么设备
  • 网站建设需求分析有什么内容小树建站平台
  • 高端建站用什么软件北京网站推广
  • 鞍山网站制作的网站以百度云做网站空间
  • 上海建设银行青浦分行网站交换友情链接推广法
  • 深圳网站导航wordpress管理员帐号
  • 网站建设与管理 市场分析个人名义做网站能备案吗
  • 山东做网站的公司有哪些哪些网站是做外贸生意的
  • 中华门窗网怎么做网站拓者吧室内设计网站
  • 网站建设技术教程视频宜兴经济开发区人才网
  • 沈阳关键词优化价格网站seo工作内容
  • 一份完整的网站策划书公众号代运营费用
  • 一个网站多个域名重定向怎么做宝坻做网站
  • 网站菜单导航制作教程什么网站可以做外国生意
  • 弹性云主机做网站哪个找房网站好
  • 网站策划网温州文成县高端网站设计
  • 免费域名申请网站空间网站做虚假宣传有没有做处罚