Vue Router进阶详解

导航守卫

若依框架登录鉴权详解(动态路由)_若依鉴权-CSDN博客

完整的导航解析流程

  1. 导航被触发

    • 当用户点击页面中的链接、使用编程式导航(如router.pushrouter.replace)或手动输入URL时,导航流程被触发。
  2. 在失活的组件里调用beforeRouteLeave守卫

    • 如果当前有激活的组件(即用户正在查看的组件),则在该组件内调用beforeRouteLeave守卫。这允许组件在离开之前执行一些清理工作或条件检查(如用户是否保存了更改)。
  3. 调用全局beforeEach守卫

    • 在路由实例上注册的全局beforeEach守卫会在导航确认之前被调用。这是一个全局的钩子,可以用于执行一些通用的检查或处理逻辑,如身份验证
  4. 在复用组件里调用beforeRouteUpdate守卫(Vue Router 2.2+):

    • 如果目标路由和当前路由使用相同的组件,并且只是参数发生了变化(如从一个用户页面导航到另一个用户页面,但两者都使用相同的User组件),则会在该组件内调用beforeRouteUpdate守卫。这允许组件在参数变化时更新其内容。
  5. 调用路由配置里的beforeEnter守卫

    • 在路由配置对象中定义的beforeEnter守卫会在导航到该路由之前被调用。这是一个路由独享的钩子,可以用于在该路由上执行一些特定的逻辑。
  6. 解析异步路由组件

    • 如果目标路由是一个异步组件,则此时会解析该异步组件。
  7. 在被激活的组件里调用beforeRouteEnter守卫

    • 在目标路由对应的组件内调用beforeRouteEnter守卫。这允许组件在渲染之前执行一些初始化工作。需要注意的是,此时组件实例尚未被创建,因此无法访问this。但可以通过向next函数传递一个回调函数来访问组件实例
  8. 调用全局beforeResolve守卫(Vue Router 2.5+):

    • 在导航被确认之前,并且在所有组件内守卫和异步路由组件被解析之后,调用全局beforeResolve守卫。这是一个全局的钩子,可以用于在导航确认之前执行一些额外的逻辑。
  9. 导航被确认

    • 此时,所有的守卫和钩子都已经被调用,并且没有守卫中断导航。路由实例现在会确认导航,并准备更新DOM。
  10. 调用全局afterEach钩子

    • 在导航完成后调用全局afterEach钩子。这是一个全局的钩子,不会接受next函数,也不会改变导航本身。它主要用于记录导航的详细信息或执行一些清理工作。
  11. 触发DOM更新

    • Vue Router会根据目标路由渲染相应的组件,并更新DOM以反映新的视图。
  12. 用创建好的实例调用beforeRouteEnter守卫中传给next的回调函数

    • 如果在beforeRouteEnter守卫中向next函数传递了一个回调函数,则此时会调用该回调函数,并将组件实例作为参数传递给它。这允许组件在渲染之后执行一些后续工作。

全局守卫(router.beforeEach与router.afterEach)

全局守卫是作用于整个Vue应用的守卫,它们会在任意路由发生改变时被调用。全局守卫主要包括全局前置守卫(router.beforeEach)和全局后置守卫(router.afterEach)。

  • 全局前置守卫:在路由跳转之前执行,可以通过调用router.beforeEach方法注册。这些守卫会按照注册顺序依次执行,并且每个守卫都有机会中断导航过程。如果守卫函数返回false或调用next(false),则导航会被中断。如果守卫函数不调用next()或调用next('/')next({ ... })进行重定向,则导航也会中断
  • 全局后置守卫:在导航完成后被调用,不接受next函数也不可以中断导航。它们主要用于做一些清理工作或者修改状态
router.beforeEach((to, from, next) => {NProgress.start()if (getToken()) {//获取路由的mata.title属性,并存储在Vuex中to.meta.title && store.dispatch('settings/setTitle', to.meta.title)/* has token*/if (to.path === '/login') {next({ path: '/' })NProgress.done()} else {if (store.getters.roles.length === 0) {isRelogin.show = true// 判断当前用户是否已拉取完user_info信息store.dispatch('GetInfo').then(() => {isRelogin.show = falsestore.dispatch('GenerateRoutes').then(accessRoutes => {// 根据roles权限生成可访问的路由表console.log(accessRoutes);router.addRoutes(accessRoutes) // 动态添加可访问路由表//通过返回新的位置来触发重定向next({ ...to, replace: true }) // hack方法 确保addRoutes已完成})}).catch(err => {store.dispatch('LogOut').then(() => {Message.error(err)next({ path: '/' })})})} else {next()}}} else {// 没有tokenif (whiteList.indexOf(to.path) !== -1) {// 在免登录白名单,直接进入next()} else {next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页NProgress.done()}}
})router.afterEach(() => {NProgress.done()
})

 路由独享守卫(beforeEnter)

是作用于单个路由或一组路由的守卫,可以在路由配置中直接定义。这种守卫允许开发者针对特定的路由实施一些逻辑,例如验证用户是否有权限访问某个页面。路由独享守卫只有一个钩子函数beforeEnter它会在进入路由时触发,不会在参数、查询字符串或哈希值改变时触发

组件内守卫(beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave。)

组件内守卫是作用于路由组件内的守卫,只能在路由组件中使用。这些守卫允许开发者在组件的生命周期钩子中控制路由导航。组件内守卫包括beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave

  • beforeRouteEnter:在组件被创建之前调用,此时组件实例尚未被创建,因此无法访问this。可以通过向next函数传递一个回调函数来访问组件实例
  • beforeRouteUpdate在当前路由改变,但是该组件被复用时调用。例如,对于一个带有动态参数的路径/foo/:id,在/foo/1/foo/2之间导航时,同一个Foo组件实例会被复用,此时会调用beforeRouteUpdate守卫。
  • beforeRouteLeave:在导航离开该组件的对应路由时被调用。它可用于在离开路由前进行一些操作,比如保存用户编辑的内容或询问用户是否确定离开。

 动态路由

  1. 权限管理:在应用中,不同用户可能有不同的访问权限。通过动态路由,我们可以在用户登录后根据其权限动态添加或删除路由,从而控制用户对不同页面的访问。
  2. 模块懒加载:对于大型应用,为了优化性能,我们可以按需加载不同模块的路由。在用户访问某个模块时,再动态添加该模块的路由配置。
  3. 动态生成菜单:在一些后台管理系统中,菜单项和对应的路由可能是动态生成的。我们可以根据后台返回的菜单配置,动态生成对应的路由。
const router = createRouter({history: createWebHistory(),routes: [{ path: '/:articleName', component: Article }],
})
router.addRoute({ path: '/about', component: About })
//页面仍然会显示 Article 组件,我们需要手动调用 router.replace() 来改变当前的位置,并覆盖我们原来的位置
router.addRoute({ path: '/about', component: About })
// 我们也可以使用 this.$route 或 useRoute()
router.replace(router.currentRoute.value.fullPath)

在导航守卫中添加路由

    如果你决定在导航守卫内部添加或删除路由,你不应该调用 router.replace(),而是通过返回新的位置来触发重定向:

 
store.dispatch('GenerateRoutes').then(accessRoutes => {// 根据roles权限生成可访问的路由表console.log(accessRoutes);router.addRoutes(accessRoutes) // 动态添加可访问路由表//通过返回新的位置来触发重定向next({ ...to, replace: true }) // hack方法 确保addRoutes已完成})
--------------------------------------------------------------------------
router.beforeEach(to => {if (!hasNecessaryRoute(to)) {router.addRoute(generateRoute(to))// 触发重定向return to.fullPath}
})

过渡效果 

原生CSS中transation与animation

CSS中的Transition(过渡效果)和Animation(动画)是实现网页动态效果的重要技术,能够提升用户体验,使网页看起来更加生动和吸引人。以下是两者的详细介绍:

一、CSS Transition(过渡效果)
  1. 基本概念

    CSS Transition允许元素从一种样式状态平滑地改变为另一种样式状态,通常用于简单的动态效果,如按钮的悬停状态、元素的显示和隐藏等。

  2. 主要属性

    • transition-property:指定应用过渡效果的CSS属性名称,如width、height、background-color等。也可以使用“all”来指定所有可动画属性。
    • transition-duration:定义过渡效果完成所需的时间,单位可以是秒(s)或毫秒(ms)。
    • transition-timing-function:描述过渡效果的速度曲线,如linear(线性)、ease(慢到快再到慢)、ease-in(慢到快)、ease-out(快到慢)和ease-in-out(慢到快再到慢,但比ease更平缓)。还可以使用cubic-bezier函数来自定义速度曲线。
    • transition-delay:定义过渡效果开始前的延迟时间,单位同样可以是秒(s)或毫秒(ms)。
    • transition:上述四个属性的简写形式,按顺序分别指定transition-property、transition-duration、transition-timing-function和transition-delay。
  3. 使用示例

    .box { 
    width: 100px; 
    height: 100px; 
    background-color: red; 
    transition: width 1s ease-in-out; 
    } .box:hover { 
    width: 200px; 
    }

    当鼠标悬停在具有“.box”类的元素上时,元素的宽度会从100px平滑地过渡到200px,过渡效果持续1秒,采用缓入缓出的时间函数。

  4. 注意事项

    • 过渡效果不会应用于display、visibility等少数CSS属性
    • 过渡效果在元素从不可见变为可见时不会触发,除非是通过改变opacity或其他可以产生类似效果的属性来实现可见性的变化。
    • 如果过渡效果的目标值与起始值相同,过渡效果将不会触发。
    • 过渡效果在元素或其父元素被隐藏(如display: none)时不会运行。
二、CSS Animation(动画)
  1. 基本概念

    CSS Animation比Transition更为强大,它允许创建更复杂的动画效果,可以包含多个步骤和关键帧。

  2. 主要属性

    • animation-name:指定要绑定到选择器的关键帧的名称。
    • animation-duration:定义动画完成一个周期需要多少秒或毫秒。
    • animation-timing-function:指定动画将如何完成一个周期,与Transition中的transition-timing-function类似,也可以使用cubic-bezier函数来自定义速度曲线。
    • animation-delay:定义动画什么时候开始,单位可以是秒(s)或毫秒(ms),也可以是负值以表示跳过部分动画。
    • animation-iteration-count:定义动画应该播放多少次,可以是具体次数或infinite(无限循环)。
    • animation-direction:定义是否循环交替反向播放动画,如normal(正向播放)、reverse(反向播放)、alternate(交替正向和反向播放)等。
    • animation-fill-mode:规定当动画不播放时(如动画完成时、有延迟未开始播放时)要应用到元素的样式,如none、forwards(动画结束时保持最后一帧的样式)等。
    • animation-play-state:指定动画是否正在运行或已暂停。
    • animation:上述属性的简写形式,按顺序分别指定各属性的值。
  3. 使用示例

    .box-max { 
    width: 100px; 
    height: 100px; 
    background-color: aqua; 
    animation-name: box1; 
    animation-duration: 3s; 
    } @keyframes box1 { 
    0% { 
    opacity: 1; 
    } 
    100% { 
    opacity: 0.3; 
    } 
    }

    这个示例创建了一个名为“.box-max”的元素,并应用了一个名为“box1”的动画。动画使元素的透明度从1逐渐变为0.3,持续时间为3秒。

  4. 注意事项

    • 使用Animation时,规需要配合@keyframes则来定义动画的关键帧。
    • 动画的性能可能会受到多个因素的影响,如动画的复杂度、元素的数量等。因此,在使用动画时需要注意性能优化,如避免对大量元素同时应用复杂的动画效果。

Vue中transition

<transition>组件会在其包裹的内容(一个元素或组件)进入和离开DOM时,自动应用过渡效果。这些过渡效果可以通过CSS过渡(transition)或CSS动画(animation)来实现。

常见属性

  1. name:用于指定过渡效果的名称。如果不指定,Vue会使用默认的类名前缀v-。指定后,Vue会使用指定的名称作为类名前缀,如fade-enter-active
  2. mode:用于设置过渡的模式。可以是in-out(先完成当前元素的过渡,然后新元素开始过渡)或out-in(先让当前元素过渡出去,然后新元素开始过渡)。默认是in-out
  3. type:指定过渡效果的类型,可以是transition(CSS过渡)或animation(CSS动画)。Vue 2.9.0+版本支持。如果不指定,Vue会根据元素的样式自动判断。
  4. duration:设置过渡效果的持续时间,单位是毫秒。可以是一个固定的值,也可以是一个对象,分别指定进入和离开的持续时间。Vue 2.9.0+版本支持。

常见钩子

  1. before-enter:进入过渡之前调用。
  2. enter:进入过渡被触发时调用。
  3. after-enter:进入过渡结束后调用。
  4. enter-cancelled:在进入过渡被取消时调用(比如通过切换v-if条件来取消过渡)。
  5. before-leave:离开过渡之前调用。
  6. leave:离开过渡被触发时调用。
  7. after-leave:离开过渡结束后调用。
  8. leave-cancelled:在离开过渡被取消时调用。

为过渡命名
<Transition name="fade">...
</Transition>.fade-enter-active,
.fade-leave-active {transition: opacity 0.5s ease;
}.fade-enter-from,
.fade-leave-to {opacity: 0;
}
与原生CSS的transition一同使用
<Transition name="slide-fade"><p v-if="show">hello</p>
</Transition>/*进入和离开动画可以使用不同持续时间和速度曲线。
*/
.slide-fade-enter-active {transition: all 0.3s ease-out;
}.slide-fade-leave-active {transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}.slide-fade-enter-from,
.slide-fade-leave-to {transform: translateX(20px);opacity: 0;
}
与原生animation一同使用 
<Transition name="bounce"><p v-if="show" style="text-align: center;">Hello here is some bouncy text!</p>
</Transition>.bounce-enter-active {animation: bounce-in 0.5s;
}
.bounce-leave-active {animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.25);}100% {transform: scale(1);}
}
深层级过渡与显式过渡时长
<Transition name="nested"><div v-if="show" class="outer"><div class="inner">Hello</div></div>
</Transition>/* 应用于嵌套元素的规则 */
.nested-enter-active .inner,
.nested-leave-active .inner {transition: all 0.3s ease-in-out;
}.nested-enter-from .inner,
.nested-leave-to .inner {transform: translateX(30px);opacity: 0;
}/* ... 省略了其他必要的 CSS *//*我们甚至可以在深层元素上添加一个过渡延迟,从而创建一个带渐进延迟的动画序列:*//* 延迟嵌套元素的进入以获得交错效果 */
.nested-enter-active .inner {transition-delay: 0.25s;
}

然而,这会带来一个小问题。默认情况下,<Transition> 组件会通过监听过渡根元素上的第一个 transitionend 或者 animationend 事件来尝试自动判断过渡何时结束。而在嵌套的过渡中,期望的行为应该是等待所有内部元素的过渡完成。

在这种情况下,你可以通过向 <Transition> 组件传入 duration prop 来显式指定过渡的持续时间 (以毫秒为单位)。总持续时间应该匹配延迟加上内部元素的过渡持续时间

<Transition :duration="550">...</Transition><Transition :duration="{ enter: 500, leave: 800 }">...</Transition>

keep-alive& transition &router-view

<router-view v-slot="{ Component }"><transition><keep-alive><component :is="Component" /></keep-alive></transition>
</router-view>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/555.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

力扣排序242题 有效的子母异位词

题目&#xff1a; 242.有效的字母异位词 给定两个字符串s和t &#xff0c;编写一个函数来判断 t是否是s的字母异位词。 示例1: 输入: s "anagram", t "nagaram" 输出: true 解题思路&#xff1a; 要判断两个字符串s和t是否为子母异位词&#xff0c;也…

html简易流程图

效果图 使用htmlcssjs&#xff0c;无图片&#xff0c;没用Canvas demo: <!DOCTYPE html> <html> <head><link href"draw.css" rel"stylesheet" /><script src"draw.js" type"text/javascript"></…

51单片机教程(一)- 开发环境搭建

1、开发环境搭建 1 环境准备 1 单片机介绍 单片机&#xff08;Single-Chip Microcomputer&#xff0c;简称MCU&#xff09;是一种集成电路芯片&#xff0c;是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、…

【1个月速成Java】基于Android平台开发个人记账app学习日记——第3天,分析项目结构

24.11.02 1.分析项目初始结构 IDEA有2种查看Android项目模式&#xff0c;一种是原始的projects模式&#xff0c;重点介绍这个模式下的项目结构 Android模式下的项目结构 这个是经过Android处理后的&#xff0c;并不是真正的项目结构&#xff0c;但是看着很简洁 projects模式…

chrome编辑替换js文件的图文教程

一、找到要修改替换的js文件 二、将文件保存到本地 三、在本地新建一个文件 路径最好跟你要替换的文件的路径保持一致&#xff0c; 四、选中js文件替换 回到原文件右击选择保存并覆盖 点击完保存并覆盖之后回到替换的新文件中&#xff0c;在自动生成的webpack文件中对文件进…

大学城水电管理:Spring Boot应用案例

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理大学城水电管理系统的相关信息成为必然。开…

硅谷15菜单权限

菜单权限 15.1 路由的拆分 15.1.1 路由分析 菜单的权限: 超级管理员账号:admin atguigu123 拥有全部的菜单、按钮的权限 飞行员账号 硅谷333 111111 不包含权限管理模块、按钮的权限并非全部按钮 同一个项目&#xff1a;不同人(职位是不一样的,他能访问到的菜单、…

3D Gaussian Splatting代码详解(二):模型构建

3 模型构建 gaussians GaussianModel(dataset.sh_degree) 3.1 初始化函数 __init__ 构造函数 构造函数 __init__ 的主要作用是初始化 3D 高斯模型的各项参数和激活函数&#xff0c;用于生成 3D 空间中的高斯表示。 初始化球谐函数的参数&#xff1a; self.active_sh_degre…

初知C++:继承

文章目录 1. 继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1 定义格式1.2.2 继承基类成员访问方式的变化 2.基类和派生类间的转换3. 继承中的作用域3.1 隐藏规则3.2 考察继承作用域相关选择题 4. 派生类的默认成员函数4.1 4个常见默认成员函数4.2实现一个不能被继承的类 5. …

Java实战项目-基于 SpringBoot+Vue 的医院管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

二分,CF 2036 G - Library of Magic

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 G - Library of Magic 二、解题报告 1、思路分析 首先 query(1, n) a ^…

【测试平台】打包 子节点ios环境配置

主要记录如何配置ios打包机环境&#xff0c;ios环境相对来说比较简单的&#xff0c;研发配置好证书可以本地打包&#xff0c;接入流程比较简单了。 打包机系统升级 1.升级mac OS系统 一般升级好几个小时&#xff0c;可以晚上下载好 2.下载xcode并安装 Appstroe 下载安装xco…

矩阵的奇异值分解SVD

为了论述矩阵的奇异值与奇异值分解!需要下面的结论!

parted 磁盘分区

目录 磁盘格式磁盘分区文件系统挂载使用扩展 - parted、fdisk、gdisk 区别 磁盘格式 parted /dev/vdcmklabel gpt # 设置磁盘格式为GPT p # 打印磁盘信息此时磁盘格式设置完成&#xff01; 磁盘分区 开始分区&#xff1a; mkpart data_mysql # 分区名&…

【Linux】权限管理

目录 一、shell&#xff1a; 二、权限&#xff1a; 1、用户理解&#xff1a; 2、文件权限&#xff1a; 3、目录权限&#xff1a; 4、权限掩码&#xff1a; 5、粘滞位&#xff1a; 一、shell&#xff1a; Linux操作系统不仅仅是指Linux内核&#xff0c;而是指基于Linux内核…

【C++ | 数据结构】八大常用排序算法详解

1. 排序的稳定性 排序是我们生活中经常会面对的问题&#xff0c;小朋友站队的时候会按照从矮到高的顺序排列&#xff1b;老师查看上课出勤情况时&#xff0c;会按照学生的学号点名&#xff1b;高考录取时&#xff0c;会按照成绩总分降序依次录取等等。那么对于排序它是如何定义…

PG数据库 jsonb字段 模糊查询

背景&#xff1a; 项目由于多语言的设计&#xff0c;将字段设置成json字段类型&#xff0c;同时存储中文和英文 页面上通过输入框实现模糊的查询 一、表结构&#xff1a;name字段设置jsonb类型 二、表数据 3、Mybatis编写sql select pp.name ->>zh-CN as pmsProductNam…

webpack使用详解

摘要&#xff1a;webpack作为一款主流的构建工具&#xff0c;对比后来者Vite虽然存在一些缺点&#xff0c;例如启动慢&#xff0c;配置复杂等。在很多项目中使用依然基于webpack构建&#xff0c;有必要掌握其概念、构建流程和配置方法。 1 webpack概述 1.1 基本概念 webpack …

【flutter列表播放器】

视频播放器类 import package:jade/configs/PathConfig.dart; import package:jade/utils/Utils.dart; import package:model/user_share/reward_pool_model.dart; import package:pages/user_share/view/user_share_article_detail_page.dart; import package:util/navigato…

Ubuntu Linux

起源与背景 Ubuntu起源于南非&#xff0c;其名称“Ubuntu”来源于非洲南部祖鲁语或豪萨语&#xff0c;意为“人性”、“我的存在是因为大家的存在”&#xff0c;这体现了非洲传统的一种价值观。Ubuntu由南非计算机科学家马克沙特尔沃斯&#xff08;Mark Shuttleworth&#xff…