vue-router(v4.0) 基础3

  1. 编程式导航

    1. 除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
    2. 导航到不同的位置
      1. 示例
      2. 该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
        // 字符串路径
        router.push('/users/eduardo')
        
        // 带有路径的对象
        router.push({ path: '/users/eduardo' })
        
        // 命名的路由,并加上参数,让路由建立 url
        router.push({ name: 'user', params: { username: 'eduardo' } })
        
        // 带查询参数,结果是 /register?plan=private
        router.push({ path: '/register', query: { plan: 'private' } })
        
        // 带 hash,结果是 /about#team
        router.push({ path: '/about', hash: '#team' })
      3. 注意:如果提供了 pathparams 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path :
        const username = 'eduardo'
        // 我们可以手动建立 url,但我们必须自己处理编码
        router.push(`/user/${username}`) // -> /user/eduardo
        // 同样
        router.push({ path: `/user/${username}` }) // -> /user/eduardo
        // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
        router.push({ name: 'user', params: { username } }) // -> /user/eduardo
        // `params` 不能与 `path` 一起使用
        router.push({ path: '/user', params: { username } }) // -> /user
      4. 当指定 params 时,可提供 string 或 number 参数(或者对于可重复的参数可提供一个数组)。任何其他类型(如对象、布尔等)都将被自动字符串化。对于可选参数,你可以提供一个空字符串("")或 null 来移除它。

        由于属性 to 与 router.push 接受的对象种类相同,所以两者的规则完全相同。

        此外,router.push 和所有其他导航方法都会返回一个 Promise,让我们可以等到导航完成后才知道是成功还是失败。

    3. 替换当前位置
      1. 它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。
      2. 也可以直接在传递给 router.push 的 to 参数中增加一个属性 replace: true :
        router.push({ path: '/home', replace: true })
        // 相当于
        router.replace({ path: '/home' })
    4. 横跨历史
      1. 该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)
        // 向前移动一条记录,与 router.forward() 相同
        router.go(1)
        
        // 返回一条记录,与 router.back() 相同
        router.go(-1)
        
        // 前进 3 条记录
        router.go(3)
        
        // 如果没有那么多记录,静默失败
        router.go(-100)
        router.go(100)

  2. 命名路由

    1. 除了 path 之外,你还可以为任何路由提供 name。这有以下优点
      1. 没有硬编码的 URL
      2. params 的自动编码/解码。
      3. 防止你在 url 中出现打字错误。
      4. 绕过路径排序(如显示一个)
        const routes = [
          {
            path: '/user/:username',
            name: 'user',
            component: User,
          },
        ]
    2. 要链接到一个命名的路由,可以向 router-link 组件的 to 属性传递一个对象:
      <router-link :to="{ name: 'user', params: { username: 'erina' }}">
        User
      </router-link>
    3. 这跟代码调用 router.push() 是一回事:
      router.push({ name: 'user', params: { username: 'erina' } })
    4. 在这两种情况下,路由将导航到路径 /user/erina。所有路由的命名都必须是唯一的。如果为多条路由添加相同的命名,路由器只会保留最后那一条。
  3. 重定向

    1. 入门
      1. 重定向也是通过 routes 配置来完成,下面例子是从 /home 重定向到 /:
        const routes = [{ path: '/home', redirect: '/' }]
      2. 重定向的目标也可以是一个命名的路由:
        const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
      3. 甚至是一个方法,动态返回重定向目标:
        const routes = [
          {
            // /search/screens -> /search?q=screens
            path: '/search/:searchText',
            redirect: to => {
              // 方法接收目标路由作为参数
              // return 重定向的字符串路径/路径对象
              return { path: '/search', query: { q: to.params.searchText } }
            },
          },
          {
            path: '/search',
            // ...
          },
        ]
      4. 请注意,导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在上面的例子中,在 /home 路由中添加 beforeEnter 守卫不会有任何效果。

        在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由:如果一个路由记录有 children 和 redirect 属性,它也应该有 component 属性。

    2. 相对重定向
      1. 也可以重定向到相对位置:
        const routes = [
          {
            // 将总是把/users/123/posts重定向到/users/123/profile。
            path: '/users/:id/posts',
            redirect: to => {
              // 该函数接收目标路由作为参数
              // 相对位置不以`/`开头
              // 或 { path: 'profile'}
              return 'profile'
            },
          },
        ]

  4. 不同的历史模式

    1. 在创建路由器实例时,history 配置允许我们在不同的历史模式中进行选择。
    2. Hash 模式
      1. hash 模式是用 createWebHashHistory() 创建的:
        import { createRouter, createWebHashHistory } from 'vue-router'
        
        const router = createRouter({
          history: createWebHashHistory(),
          routes: [
            //...
          ],
        })

        它在内部传递的实际 URL 之前使用了一个哈希字符(#)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响。如果你担心这个问题,可以使用 HTML5 模式。

    3. Memory 模式
      1. Memory 模式不会假定自己处于浏览器环境,因此不会与 URL 交互也不会自动触发初始导航。这使得它非常适合 Node 环境和 SSR。它是用 createMemoryHistory() 创建的,并且需要你在调用 app.use(router) 之后手动 push 到初始导航。
        import { createRouter, createMemoryHistory } from 'vue-router'
        const router = createRouter({
          history: createMemoryHistory(),
          routes: [
            //...
          ],
        })

        虽然不推荐,你仍可以在浏览器应用程序中使用此模式,但请注意它不会有历史记录,这意味着你无法后退前进

    4. HTML5 模式
      1. 用 createWebHistory() 创建 HTML5 模式,推荐使用这个模式:
        import { createRouter, createWebHistory } from 'vue-router'
        
        const router = createRouter({
          history: createWebHistory(),
          routes: [
            //...
          ],
        })

        当使用这种历史模式时,URL 会看起来很 "正常",例如 https://example.com/user/id。漂亮!

        不过,问题来了。由于我们的应用是一个单页的客户端应用,如果没有适当的服务器配置,用户在浏览器中直接访问 https://example.com/user/id,就会得到一个 404 错误。这就尴尬了。

        不用担心:要解决这个问题,你需要做的就是在你的服务器上添加一个简单的回退路由。如果 URL 不匹配任何静态资源,它应提供与你的应用程序中的 index.html 相同的页面。漂亮依旧!

  5. 导航守卫

    1. 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
    2. 全局前置守卫
      1. 可以使用 router.beforeEach 注册一个全局前置守卫:
        const router = createRouter({ ... })
        
        router.beforeEach((to, from) => {
          // ...
          // 返回 false 以取消导航
          return false
        })
      2. 当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。

        每个守卫方法接收三个参数:

        1. to: 即将要进入的目标 用一种标准化的方式

        2. from: 当前导航正要离开的路由 用一种标准化的方式

        3. next:在之前的 Vue Router 版本中,还可以使用 第三个参数 next 。这是一个常见的错误来源,我们经过 RFC 讨论将其移除。然而,它仍然是被支持的,这意味着你可以向任何导航守卫传递第三个参数。在这种情况下,确保 next 在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。这里有一个在用户未能验证身份时重定向到/login的错误用例:

          // BAD
          router.beforeEach((to, from, next) => {
            if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
            // 如果用户未能验证身份,则 `next` 会被调用两次
            next()
          })

          下面是正确的版本:

          // GOOD
          router.beforeEach((to, from, next) => {
            if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
            else next()
          })
        4. 可以返回的值如下:

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

          2. ​一个路由地址: 通过一个路由地址重定向到一个不同的地址,如同调用 router.push(),且可以传入诸如 replace: true 或 name: 'home' 之类的选项。它会中断当前的导航,同时用相同的 from 创建一个新导航。

             router.beforeEach(async (to, from) => {
               if (
                 // 检查用户是否已登录
                 !isAuthenticated &&
                 // ❗️ 避免无限重定向
                 to.name !== 'Login'
               ) {
                 // 将用户重定向到登录页面
                 return { name: 'Login' }
               }
             })

            如果遇到了意料之外的情况,可能会抛出一个 Error。这会取消导航并且调用 router.onError() 注册过的回调。

            如果什么都没有,undefined 或返回 true,则导航是有效的,并调用下一个导航守卫

            以上所有都同 async 函数 和 Promise 工作方式一样:

            router.beforeEach(async (to, from) => {
              // canUserAccess() 返回 `true` 或 `false`
              const canAccess = await canUserAccess(to)
              if (!canAccess) return '/login'
            })
    3. 全局解析守卫
      1. 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,因为它在每次导航时都会触发,不同的是,解析守卫刚好会在导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用。这里有一个例子,确保用户可以访问自定义 meta 属性 requiresCamera 的路由:
        router.beforeResolve(async to => {
          if (to.meta.requiresCamera) {
            try {
              await askForCameraPermission()
            } catch (error) {
              if (error instanceof NotAllowedError) {
                // ... 处理错误,然后取消导航
                return false
              } else {
                // 意料之外的错误,取消导航并把错误传给全局处理器
                throw error
              }
            }
          }
        })

        router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。

    4. 全局后置钩子
      1. 也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
        router.afterEach((to, from) => {
          sendToAnalytics(to.fullPath)
        })
      2. 它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

        它们也反映了 navigation failures 作为第三个参数:

        router.afterEach((to, from, failure) => {
          if (!failure) sendToAnalytics(to.fullPath)
        })
  6. 路由元信息

    1. 有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 meta 字段:
      const routes = [
        {
          path: '/posts',
          component: PostsLayout,
          children: [
            {
              path: 'new',
              component: PostsNew,
              // 只有经过身份验证的用户才能创建帖子
              meta: { requiresAuth: true },
            },
            {
              path: ':id',
              component: PostsDetail
              // 任何人都可以阅读文章
              meta: { requiresAuth: false },
            }
          ]
        }
      ]
    2. 那么如何访问这个 meta 字段呢?

      首先,我们称呼 routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录。

      例如,根据上面的路由配置,/posts/new 这个 URL 将会匹配父路由记录 (path: '/posts') 以及子路由记录 (path: 'new')。

      一个路由匹配到的所有路由记录会暴露为 $route 对象(还有在导航守卫中的路由对象)的$route.matched 数组。我们需要遍历这个数组来检查路由记录中的 meta 字段,但是 Vue Router 还为你提供了一个 $route.meta 方法,它是一个非递归合并所有 meta 字段(从父字段到子字段)的方法。这意味着你可以简单地写

      router.beforeEach((to, from) => {
        // 而不是去检查每条路由记录
        // to.matched.some(record => record.meta.requiresAuth)
        if (to.meta.requiresAuth && !auth.isLoggedIn()) {
          // 此路由需要授权,请检查是否已登录
          // 如果没有,则重定向到登录页面
          return {
            path: '/login',
            // 保存我们所在的位置,以便以后再来
            query: { redirect: to.fullPath },
          }
        }
      })

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Panasonic松下PLC如何数据采集?如何实现快速接入IIOT云平台?

在工业自动化领域&#xff0c;数据采集与远程控制是提升生产效率、优化资源配置的关键环节。对于使用Panasonic松下PLC的用户来说&#xff0c;如何实现高效、稳定的数据采集&#xff0c;并快速接入IIOT云平台&#xff0c;是摆在他们面前的重要课题。HiWoo Box工业物联网关以其强…

fs方法举例

fs.readFile() 读取文件 const fs require(node:fs) const path require(node:path) const s path.resolve(__dirname, ./hello.txt) const buf fs.readFileSync(s) console.log(buf.toString())输出的Buffer对象 用toString()方法转字符串之后 fs.appendFile() 创建新…

景联文科技:提供通用多模态数据,助力AI多模态领域实现飞跃式发展

回顾2023年&#xff0c;以ChatGPT为代表的通用人工智能大模型在全球范围内掀起了新一轮人工智能产业发展浪潮&#xff0c;我国人工智能大模型市场呈现百“模”争鸣、日新月异的迅猛发展态势。 根据大模型之家、钛媒体数据&#xff0c;2023年中国大模型市场规模达到147亿人民币&…

CMU 10-414/714: Deep Learning Systems --hw3

实现功能 在ndarray.py文件中完成一些python array操作 我们实现的NDArray底层存储就是一个一维向量&#xff0c;只不过会有一些额外的属性&#xff08;如shape、strides&#xff09;来表明这个flat array在维度上的分布。底层运算&#xff08;如加法、矩阵乘法&#xff09;都…

《优化接口设计的思路》系列:第九篇—用好缓存,让你的接口速度飞起来

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 作为一名从业已达六年的老码农&#xff0c…

Android14音频进阶:AudioFlinger究竟如何混音?(六十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

开源离线语音识别输入工具CapsWriter v1.0——支持无限时长语音、音视频文件转录字幕。

分享一款开源离线语音识别输入工具&#xff0c;支持无限时长语音、音视频文件转录字幕。 软件简介&#xff1a; CapsWriter是一款免费开源且可完全离线识别的语音输入工具&#xff0c;无需担心因在线版本识别带来的各种隐私泄露问题。支持win7及以上的系统&#xff0c;已经更…

洛谷_P1104 生日_python写法

P1104 生日 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 知识点&#xff1a; 还是自定义规则的排序&#xff0c;然后这里还有python中如何在一行中输入多种类型的数据。 n int(input()) data [] num 1 for i in range(n):img list(input().split())s img[0]y int(img…

Axure RP10汉化版获取:低成本高效率操作!

作为市场份额最高的专业原型设计工具&#xff0c;Axure RP10 毫无疑问&#xff0c;功能的强大性和灵活性也受到许多产品经理和设计师的青睐。许多世界百强公司也在使用Axure进行原型设计 RP10。但对于许多本土设计师来说&#xff0c;Axure RP10 全英语界面和陡峭的学习曲线让人…

图解CodeWhisperer的安装使用

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; CodeWhisperer简介 &#…

CCIE-04-Layer2_WAN_TS

目录 实验条件网络拓朴 路由器配置开始排错&#xff0c; 要求R11可以访问R17的telnet检查R12和R11的e0/0口&#xff0c;有发现检查R17和R12的S4/0口&#xff0c; 有发现ping R17环回口地址&#xff0c;发现不通telnet R17环回口IP 实验条件 网络拓朴 路由器配置 R11 4组以太网…

qt-pdf-viewer-library 编译过程记录

1.qtpdfviewerinitializer.h 中 类模板问题需要修改为下面代码: https://github.com/develtar/qt-pdf-viewer-library 下载代码&#xff1a; 编译出现错误 修改代码&#xff0c;如下: 2.无法触发onViewerLoaded 事件&#xff0c;就是界面无法显示PDF文件 修改下面代码&#…

【技巧】ChatGPT Prompt 提示语大全

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 主要来自&#xff1a;https://github.com/f/awesome-chatgpt-prompts ChatGPT SEO prompts ChatGPT SEO提示 Contributed by: StoryChief AI Reference: 7 Powerful ChatGPT Prompts to Create SEO Content Faste…

RabbitMQ问题

如何实现顺序消费&#xff1f; 消息放入到同一个队列中消费 如何解决消息不丢失&#xff1f; 方案&#xff1a; 如上图&#xff1a;消息丢失有三种情况&#xff0c;解决了以上三种情况就解决了丢失的问题 1、丢失1--->消息在到达交换机的时候&#xff1b;解决&#xff1…

RabbitMQ 安装保姆级教程

目录 1.MQ引言 1.1 什么是MQ 1.2 MQ有哪些 1.3 不同MQ特点 2.RabbitMQ 的引言 2.1 RabbitMQ 2.2 RabbitMQ 的安装 2.2.1 下载 2.2.2 下载的安装包 2.2.3 安装步骤 3. RabiitMQ 配置 3.1RabbitMQ 管理命令行 3.2 web管理界面介绍 3.2.1 overview概览 3.2.2 Admin用…

整型数组按个位值排序 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 给定一个非空数组(列表)&#xff0c;其元素数据类型为整型&#xff0c;请按照数组元素十进制最低位从小到大进行排序&#xff0c;十进制最低位相同的元素&#xf…

wireshark windows 抓包https

windows下 1.配置环境变量以生成ssl协商会话密钥日志记录 系统设置-》高级设置-》环境变量 新增环境变量 SSLKEYLOGFILE C:\Users\Public\Documents\SSLKEY\sslkey.log 打开公用共享文档创建SSLKEY文件夹用于后续系统存放协商密钥日志 2.配置Wireshark选项进行抓包 点击…

计算机二级(Python)真题讲解每日一题:《方菱形》

描述‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬ 请写代码替换横线&#xff0…

【2024最新版,redis7】redis底层的10种数据结构

前言&#xff1a;本文redis版本&#xff1a;7.2.4 本文语雀原文地址&#xff08;首发更新&#xff09;&#xff1a;https://www.yuque.com/wzzz/redis/xg2cp37kx1s4726y 本文CSDN转载地址&#xff1a; https://blog.csdn.net/u013625306/article/details/136842107 1. 常见的数…

.htaccess全站设置SSL,wordpress全站设置SSL,网站重定向的次数过多”错误最佳解决方法教程

.htaccess全站设置SSL,wordpress全站设置SSL&#xff0c;网站重定向的次数过多”错误最佳解决方法教程 网上找了很多教程网无效**.htacces**设置&#xff0c;访问后台出现重定向次数过多&#xff0c;导致无法访问 找了好久&#xff0c;测试用AI机器人无法解决&#xff0c;参考…
最新文章