第十二章:vue路由进阶使用

简介: 第十二章:vue路由进阶使用

第十二章:vue路由进阶使用

回顾:

路由:本质:一组对应关系 路径===》组件

配置路由规则 routes name:‘命名路由’ path:‘路径’ component=()=>import 一级路由 /

嵌套路由:children:[] 不用加/

访问二级路由时,需要带上一级路由

动态路由:/:name 占位符

参数:1.路由参数 2.查询参数 query:{} params:{}

重定向 redirect

router-link router-view

本章内容

  • 掌握vue路由的历史操作
  • 掌握编程式路由的使用方法
  • 掌握路由守卫的使用方法

一、vue路由的历史和编程式路由导航

1.1 vue路由的历史管理

简介: 在之前的原生js中 我们可以通过一些方式去控制网页跳转的历史记录,在vue中我们同样也可以对页面渲染组件的历史进行管理。

浏览器历史记录介绍:

**历史记录栈:**浏览器有一个数据结构来存储网页的历史记录,我们把它称之为历史记录栈,因为它的结构跟栈的使用方式有些相似。由于现在的浏览器都是多选项卡的模式,当你打开一个选项卡的时候,即使没有访问具体网页,浏览器也为这个选项卡创建好了BOM对象,比如history对象,然后把新选项卡的空白页作为历史记录里面的第一条记录。

**访问指针:**跟历史记录栈一起的,浏览器还有一个访问指针来表示当前网页在历史记录栈中的位置。默认情况下,当我们改变网页地址的时候,都会把新的页面压入到历史记录栈的顶部,同时把指针指向到这个最新的网页,每次改变了页面,当前页面的指针始终指向的是历史记录栈最顶部的那条记录;当我们通过浏览器的前进后退功能(包括按钮,快捷,右键菜单等方式)或者是history提供的go/back/forward方法,都不会改变历史记录栈的内容,只会移动一下这个指针:

  1. 前进功能/go(1)/forward,只是让这个指针上移1个位置;
  2. 后退功能/go(-1)/back,只是让这个指针下移1个位置;
  3. go(n)让指针上移n个位置;go(-n)让指针下移n个位置。

**浏览器的历史记录限制:**浏览器对历史记录的管理还有一个要点就是对历史记录栈的存储总数有限制,chrome和firefox都是50。当历史记录栈的存储的量超出这个限制后,历史记录的存储就会采取滚动的方式存储,也就是新的记录会压入到栈的顶部,最底部的记录会从栈的底部移除出去。

1.2 vue路由对历史记录的管理模式

在vue路由中我们主要通过 标签来控制对历史记录得管理,主要有以下两种模式:

  • push 模式(追加模式) 默认开启得就是push 模式 效果跟上边得介绍一样
  • replace模式: (替换模式)
    这个模式的开启需要我们在标签中添加属性:replace='true'可以简写成replace
<router-link replace active-class="router-link-active" to="/Subject">学科管理</router-link>
  • 只要我们在标签中添加一个replace属性 那么这个历史就会替换掉历史记录栈中最新的一条记录。

1.3 编程式路由导航

**导航分类:**编程式路由导航,声明式路由导航。

声明式 编程式
<router-link :to="..."> router.push(...)
<router-link :to="..." replace> router.replace(...)
1.3.1 概念:

除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

也就是说在我们之前的代码示例中,只要跳转组件,就一定要通过路由才可以;但是我们在实际开发中有些时候(某一些组件跳转时),可能不方便使用路由来完成,此时我们可能是需要页面中有一个按钮,我们点击按钮,不触发路由,而是通过js代码的方式来完成组件的跳转(例如:3秒后自动跳转)。这种方式被称为 编程式路由导航

1.3.2 使用
  • **router.push()**方法
#在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:

当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(...)

// 字符串此时直接去匹配index.js路由中的path路径
router.push('home')
// 对象
router.push({ path: 'home'})
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
  • router.replace()

router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

  • router.forward() & router.back()
    前进和后退一步:
<button type="button" @click="$router.forward()">前进</button>
<button type="button" @click="$router.back()">后退</button>
  • router.go()

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)

二、路由导航守卫(重点)

拦截器

2.1 简介

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

简单来说,导航守卫就是路由跳转前、中、后过程中的一些钩子函数,这个函数能让你操作一些其他的事儿,这就是导航守卫

例如:通过路由拦截,来判断用户是否登录,该页面用户是否有权限浏览

2.2 全局前置守卫

**概念:**当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中

在项目中 每次发生路由的导航跳转时,都会触发这个全局前置守卫,类似于高铁站的安检,必须经过安检的检查后才可以进入。也就是说 必须先通过 全局前置守卫的检查 才可以完成组件的跳转。因此全局前置守卫可以对路由的跳转进行权限的控制。

使用:router.beforeEach(fn) 在index.js中声明路由VueRouter对象之后,给这个VueRouter对象添加 beforeEach()方法,完成全局前置守卫。

确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

//定义全局前置守卫
router.beforeEach(function(to,from,next){
  //to   是预期要访问的路由对象    到哪里去
    //from 是将要离开的路由对象    从那里来
    //next 是一个函数  表示放行  有三种用法
      next() 表示放行
        next('/login') 表示强制跳转指定路径
        next(false) 表示不允许访问  停留在当前页面
})

案例:登录验证+退出登录

登录流程: 单点登录 会给用户返回一个信息:token 在外人看来就是一段无意义的字符串。

第一步:

当我们登录成功后,后端会给我们返回一个token认证信息,我们要把这个token 信息存储在本地(localStorage,sessionStorage)

第二步:

在前端 路由中使用 全局前置守卫 来做判断 路由放行的条件!!!

登录拦截操作

路由放行的条件,问:什么时候 路由可以放行?

  1. /login 必须放心 如果不放行 我们压根儿没法登录 所以也就没法获取token
  2. 有localStorage中 存在 token 信息
  3. 设置/index为整个项目的根目录,只要之后的路径访问中 含有/login 就放行。

第三步:退出登录

  1. 清除token 2. 路由导航到登录页
在index.js文件中定义
//添加配置路由的守卫
router.beforeEach(function (to, from, next) {
    //to :    到哪里去  对象类型  将要访问的路由对象
    //from:   从哪里来  对象类型  离开的路由对象
    //next:   放行      函数类型
    //需求:把stu拦截了。
    /*登录拦截操作
        路由放行的条件,问:什么时候 路由可以放行?
            1. /login 必须放心 如果不放行 我们压根儿没法登录 所以也就没法获取token
            2.有localStorage中 存在 token 信息
            3.设置/index为整个项目的根目录,只要之后的路径访问中 含有/login 就放行。
    */
    let token = localStorage.getItem('token');
    //console.log(token)
    if (to.path == '/login') {
        //console.log(to.path)
        //如果token存在 就放行
        if (token) {
            next('/index')
        } else {
            next()
        }
    }else if(to.path.includes('/index')){
        if(token){
            next()
        }else{
            next('/login')
        }
    }else{
        //当访问的路径中不包含 /login  /index时 我就默认 你压根没有登录
        next('/login')
    }
})

退出登录:先清空localStorage中存储的登录认证信息。再把页面重定向到登录页。

路由对象的meta属性:表示路由对象的元数据

路由配置对象不像普通的js对象那样,我们可以随意的给对象添加属性,路由对象,我们无法添加 规定配置项之外的属性,但是如果我们真的想添加一些自己需要的数据的时候,我们可以使用内置提供的meta属性也是一个对象类型。可以用于对访问权限进行更加精细的设计或者跳转组件改变页面的标题。

2.3 全局后置守卫

**概念:**你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

**前置守卫:**路由跳转之前执行

**后置守卫:**路由跳转之后执行

**场景案例:**组件跳转后可以修改 页签上的标题文字:借助router路由配置对象上的属性meta来完成

语法格式:

在index.js文件中定义
//定义全局后置路由守卫
router.afterEach(function(to ,from ){
  console.log('后置守卫执行了')
  document.title = to.meta.title
})

2.4 独享路由守卫

场景:如果我们想对某一个路由做配置,例如:权限访问限制,此时 使用 全局守卫也可以完成,但是太麻烦了 一个两个 还可以, 如果要守卫的路由比较多 就麻烦了。所以可以使用 独享路由守卫单独的去控制某一个路由

**概念:**单独给某一个路由进行守卫配置,作用跟全局路由守卫一样,但是执行顺序是 先全局再独享。

在index.js文件中指定的路由上配置
#可以路由配置上直接定义 beforeEnter 守卫:
{
    path:'/about',
    name:'about',
    //配置独享路由守卫
                beforeEnter(to, from, next) {
                    /* console.log('stu的独享路由守卫被执行了')
                    next() */
                    if(to.meta.st){
                        next()
                    }else{
                        alert('无权访问')
                        next(false)
                    }
                }
}

2.5 组件内守卫

**概念:**单独给某一个组件设置路由守卫,可以定义一些业务逻辑操作

定义位置: 路由组件内

#可以在路由组件内直接定义以下路由导航守卫:
# beforeRouteEnter beforeRouteUpdate beforeRouteLeave
# About.vue 
beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }

独享路由守卫和组件内守卫功能很类似,都可以做到更精细化的权限控制操作。

2.6 路由的两种模式

  • hash模式
    默认为hash模式 也就是说路径中带有 # 并且这个#号后边的信息不会被发送到后台服务器中。
  • history模式
    可以通过在index.js文件中添加 mode选项 把默认的hash模式修改为history模式 ,这个模式在路径访问时没有#号
const router = new Router({
   mode:'history',
  routes: []
})

2.7 项目发布可能会遇到的问题

使用node.js搭建服务器来模拟项目的部署:

**第一步:**执行 npm run build 命令打包项目 会在项目下生成 dist目录

第二步: 把打包后的项目部署到服务器上

在hash模式下打包 部署到服务器运行上没有任何问题

但是在history模式下 部署运行 只在浏览器端点击是没有任何问题的,但是只要刷新页面就会出现404错误。

第三步:解决以上问题注意:必须要在服务器端才能解决这个问题。借助于第三方包

安装包: npm i --save connect-history-api-fallback

node.js服务器中的文件:

const express = require('express');
//导入安装的history包
const history = require('connect-history-api-fallback')
let app = express();
const cors = require('cors');
//设置跨域
app.use(cors());
//应用history包
app.use(history())
//设置静态资源访问
app.use(express.static(__dirname+'/public'))
app.get('/login',(req,resp)=>{
  console.log(req.url)
  resp.send("你好哈哈哈")
})
app.get('/index',(req,resp)=>{
  console.log(req.url)
  resp.send("这是Index的请求")
})
app.listen(5500,()=>{
  console.log('127.0.0.1:5500');
});

三、总结与作业

总结并掌握今日知识点。


目录
相关文章
|
22天前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
162 0
|
22天前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
1月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
137 17
|
1月前
|
监控 JavaScript 前端开发
Vue 文件批量下载组件封装完整使用方法及优化方案解析
本文详细介绍了批量下载功能的技术实现与组件封装方案。主要包括两种实现方式:**前端打包方案(基于file-saver和jszip)** 和 **后端打包方案**。前者通过前端直接将文件打包为ZIP下载,适合小文件场景;后者由后端生成ZIP文件流返回,适用于大文件或大量文件下载。同时,提供了可复用的Vue组件`BatchDownload`,支持进度条、失败提示等功能。此外,还扩展了下载进度监控和断点续传等高级功能,并针对跨域、性能优化及用户体验改进提出了建议。可根据实际需求选择合适方案并快速集成到项目中。
158 17
|
1月前
|
JavaScript 前端开发 UED
Vue 手风琴实现的三种常用方式及长尾关键词解析
手风琴效果是Vue开发中常见的交互组件,可节省页面空间、提升用户体验。本文介绍三种实现方式:1) 原生Vue结合数据绑定与CSS动画;2) 使用Element UI等组件库快速构建;3) 自定义指令操作DOM实现独特效果。每种方式适用于不同场景,可根据项目需求选择。示例包括产品特性页、后台菜单及FAQ展示,灵活满足多样需求。附代码示例与资源链接,助你高效实现手风琴功能。
102 10
|
1月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件的实现代码:支持自定义表情库、快捷键发送和输入框联动的聊天表情解决方案
本文详细介绍了在 Vue 项目中实现一个功能完善、交互友好的表情包输入组件的方法,并提供了具体的应用实例。组件设计包含表情分类展示、响应式布局、与输入框的交互及样式定制等功能。通过核心技术实现,如将表情插入输入框光标位置和点击外部关闭选择器,确保用户体验流畅。同时探讨了性能优化策略,如懒加载和虚拟滚动,以及扩展性方案,如自定义主题和国际化支持。最终,展示了如何在聊天界面中集成该组件,为用户提供丰富的表情输入体验。
111 8
|
1月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
74 1
|
1月前
|
JavaScript API 开发者
Vue框架中常见指令的应用概述。
通过以上的详细解析,你应该已经初窥Vue.js的指令的威力了。它们是Vue声明式编程模型的核心之一,无论是构建简单的静态网站还是复杂的单页面应用,你都会经常用到。记住,尽管Vue提供了大量预定义的指令,你还可以创建自定义指令以满足特定的需求。为你的Vue应用程序加上这些功能增强器,让编码变得更轻松、更愉快吧!
34 1
|
1月前
|
存储 JavaScript 前端开发
如何高效实现 vue 文件批量下载及相关操作技巧
在Vue项目中,实现文件批量下载是常见需求。例如文档管理系统或图片库应用中,用户可能需要一次性下载多个文件。本文介绍了三种技术方案:1) 使用`file-saver`和`jszip`插件在前端打包文件为ZIP并下载;2) 借助后端接口完成文件压缩与传输;3) 使用`StreamSaver`解决大文件下载问题。同时,通过在线教育平台的实例详细说明了前后端的具体实现步骤,帮助开发者根据项目需求选择合适方案。
93 0
|
1月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
44 0