【Vue】VueRouter路由

news2024/9/20 10:44:20

系列文章目录

第七章 VueRouter路由


文章目录

  • 系列文章目录
  • 第一节:VueRouter基础
    • 一、安装:
    • 二、基本使用:
      • 1. 创建路由代码:Single Page Application:SPA
      • 2. 使用路由
      • 3. 展示路由:
    • 二、嵌套路由
    • 三、路由传参
      • 1. 路由指定参数
      • 2. 查询字符串传参
    • 四、编程式导航
      • 1. router.push跳转:
      • 2. router.replace替换
  • 第二节:VueRouter进阶
    • 一、导航守卫
      • 1. 全局守卫:
      • 2. 组件内导航守卫:
      • 3. 路由导航守卫:
  • 二、路由元信息


第一节:VueRouter基础

在网页中,经常需要发生页面更新或者跳转。这时候我们就可以使用Vue-Router来帮我们实现。Vue-Router是用来做路由的,也就是定义url规则与具体的View映射的关系。可以在一个单页面中实现数据的更新。

一、安装:

通过命令:npm install vue-router@4.3.0 --save ,或者在创建项目的时候,选择添加Vue-Router的支持。

二、基本使用:

1. 创建路由代码:Single Page Application:SPA

在src/router/index.js中,填入以下代码:

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router

以上代码解释如下:

  1. 使用createRouter创建路由对象。
  2. 路由工作模式,有两种工作模式:
  • history模式:路由中不包含#,更加美观,但是在后期部署后,如果前端项目代码和后端项目代码部署在同一个域名下,则容易产生路由混淆(前端路由和后端路由混淆在一起了)。以上代码用的是history模式,代码为:
const router = createRouter({
    history:createWebHistory(), //history模式
})
  • hash模式:路由中包含#,不太美观,对SEO优化不够友好。好处是兼容性更好,即使前端代码和后端代码部署在同一个域名下,也不会产生路由混淆。使用hash模式的代码为:
const router = createRouter({
    history:createWebHashHistory(), //hash模式
})
  1. routes是一个数组,里面是对象数据,每个对象中的属性作用分别如下:
  • path:该路由对应的path。
  • component:组件对象,既可以先导入,也可以指定组件的时候使用import语句来导入。
  • name:路由名称,后期在做路由反转的时候可以使用。

2. 使用路由

然后在main.js文件中对router进行使用:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(router)

app.mount('#app')

以上相关代码解释如下:
从src/router/index.js中导入router对象。
执行app.use(router)代码,即可使用此路由了。

3. 展示路由:

在App.vue中的代码如下:

<script setup>
import { RouterLink, RouterView } from 'vue-router'
</script>

<template>
  <header>
    <div class="wrapper">
      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
      </nav>
    </div>
  </header>

  <RouterView />
</template>

以上相关代码解释如下:
在模板中,使用RouterLink定义路由链接,此组件有点类似html中的a标签,在点击后会跳转到to属性指定的路由上去。to除了直接写path外,还可以通过name来定义,比如:

<RouterLink :to="{name: 'home'}">Home</RouterLink>

使用RouterView标识路由出口,在进入路由A后,路由A所对应的组件会显示在RouterView的地方。

二、嵌套路由

在某个页面中,如果还需要通过路由更新局部模块,那么可以通过嵌套路由来实现,只要配置children就可以了。

  1. src/router/index.js代码如下:
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },{
      path: '/news',
      component: () => import('../views/news/NewsView.vue'),
      name: 'news',
      children: [{
        path: 'detail', 
        name: 'news-detail', 
        component: import('../views/news/NewsDetailView.vue')
      }]
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})
  1. src/views/news/NewsView.vue代码如下:
<template>
<ul>
    <li><RouterLink :to="{name: 'news-detail'}">新闻1</RouterLink></li>
    <li>新闻2</li>
    <li>新闻3</li>
</ul>
<RouterView></RouterView>
</template>
  1. src/views/news/NewsDetailView.vue代码如下:
<template>
<h1>AIGC将迎来爆发式增长!</h1>
</template>

三、路由传参

路由传参有两种方式,一种是在定义路由的时候指定参数,另一种是通过查询字符串的方式传参。

1. 路由指定参数

src/router/index.js代码如下:

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    path: '/news',
    component: () => import('../views/news/NewsView.vue'),
    name: 'news',
    children: [{
      path: 'detail/:pk',
      name: 'news-detail',
      component: import('../views/news/NewsDetailView.vue')
    }]
    }
  ]
})

在使用这个路由的时候,其代码如下:

<RouterLink :to="{name: 'news-detail', params: {pk: 1}}">新闻1</RouterLink>

以后在NewsDetailView.vue的onMounted生命周期函数中可以通过以下方式获取到参数:

<script setup name="NewsDetailView">
  import { onMounted } from 'vue';
  import { useRoute } from 'vue-router';

  const route = useRoute();

  onMounted(() => {
    const pk = route.params.pk;
    console.log(pk);
  })
</script>

2. 查询字符串传参

使用查询字符串传参,不需要预先在路由定义的时候指定参数,使用的时候直接传递即可,示例代码如下:/news/detail?pk=1&page=2

<RouterLink :to="{name: 'news', query: {page: 1}}">News</RouterLink>

以后在NewsView.vue组件中的onMounted生命周期函数中通过以下代码即可获取到:

四、编程式导航

之前我们学习了使用可以在用户点击的情况下进行页面更新。但有时候我们想要在js中手动的修改页面的跳转,这时候就需要使用编程式导航了。

1. router.push跳转:

想要导航到不同的URL,则使用router.push方法。这个方法会向history栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的URL。
当你点击时,这个方法会在内部调用,所以说,点击等同于调用router.push(…)。
示例代码如下:

<script setup>
  import {useRouter} from "vue-router";

  const router = useRouter();

  // 字符串路径
  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' })
</script>

注意:如果提供了 path,params 会被忽略,上述例子中的 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

2. router.replace替换

它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。
也可以直接在传递给 router.push 的 to 参数中增加一个属性 replace: true :

router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })

第二节:VueRouter进阶

一、导航守卫

导航守卫分为:全局守卫、组件导航守卫以及路由导航守卫。下面分别来进行讲解。

1. 全局守卫:

全局守卫有beforeEach 和afterEach ,即在跳转前和跳转后的导航守卫。
首先看下beforeEach,示例代码如下:

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

如果beforeEach的回调函数中返回的是true或者什么都没返回,则跳转到默认的路由,否则跳转到返回的路由。
afterEach导航路由为已经改变完成后的守卫。示例代码如下:

router.afterEach(function(to,from){
  console.log('to:',to);
  console.log('from:',from);
})

2. 组件内导航守卫:

组件内导航守卫只能使用以下两个方法:
onBeforeRouteLeave:在离开当前路由前调用。如果返回false,将会取消路由离开。比如:

router.afterEach(function(to,from){
  console.log('to:',to);
  console.log('from:',from);
})

onBeforeRouteUpdate:在路由发生更新时调用,比如从/user/1更新到/user/2,就会执行该守卫方法。一般这个方法用的比较少。

3. 路由导航守卫:

在定义路由的时候,可以指定beforeEnter导航守卫,示例代码如下:

const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
]

二、路由元信息

有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 meta 字段:

const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 只有经过身份验证的用户才能创建帖子
        meta: { requiresAuth: true },
      },
      {
        path: ':id',
        component: PostsDetail
        // 任何人都可以阅读文章
        meta: { requiresAuth: false },
      }
    ]
  }
]

那么以后可以通过路由.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.coloradmin.cn/o/2148698.html

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

相关文章

力扣718-最长重复子数组(Java详细题解)

题目链接&#xff1a;718. 最长重复子数组 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 dp五部曲。 1.确定dp数组和i下标的含义。 2.确定递推公式。 3.dp初始化。 4.确定dp的遍历顺序。 5…

【CMake】使用CMake在Visual Studio内构建多文件夹工程

一、配置准备 打开VIsual Studio&#xff0c;载入写好的 C M a k e l i s t s . t x t CMakelists.txt CMakelists.txt&#xff0c;在项目中添加以下文件&#xff1a; 创建一个文件夹 f u n c s funcs funcs&#xff0c;里面放入 f u n c . h func.h func.h、 f u n c . c p …

fmql之驱动程序编写(首次)

看了正点原子的zynq系列的Linux开发指南&#xff08;pdf和视频均有&#xff09;&#xff0c;因此从最简单的程序开始。 驱动程序开发&#xff1a;&#xff08;第四期视频&#xff09; 第3.1讲 我的第一个Linux驱动-字符设备驱动框架_哔哩哔哩_bilibili 学习驱动程序编写之前&am…

【论文串烧】多媒体推荐中的模态平衡学习 | 音视频语音识别中丢失导致的模态偏差对丢失视频帧鲁棒性的影响

文章目录 一、多媒体推荐中的模态平衡学习1.1 研究背景1.2 解决问题1.3 实施方案1.4 文章摘要1.5 文章重点1.6 文章图示图 1&#xff1a;不同模型变体在 AmazonClothing 数据集上的初步研究图 2&#xff1a;CKD模型架构的说明图 3&#xff1a;在 Amazon-Clothing 数据集上训练过…

【Linux:共享内存】

共享内存的概念&#xff1a; 操作系统通过页表将共享内存的起始虚拟地址映射到当前进程的地址空间中共享内存是由需要通信的双方进程之一来创建但该资源并不属于创建它的进程&#xff0c;而属于操作系统 共享内存可以在系统中存在多份&#xff0c;供不同个数&#xff0c;不同进…

Qt窗口——QStatusBar

文章目录 状态栏状态栏创建状态栏显示临时消息状态栏添加子控件 状态栏 QStatusBar状态栏是应用程序中输出简要信息的区域&#xff0c;例如画图板下面的区域 我们也可以给程序设置状态栏&#xff0c;表示一些状态。 状态栏创建 使用Qt Creator创建项目的时候&#xff0c;如果…

实现一种可插拔的参数校验

1、概述 仿照mybatis的二级缓存的实现方式&#xff0c;使用“策略模式配置” 的方式实现一个可动态插拔的 参数校验&#xff0c;便于后期扩展。 实现方式也很简单&#xff0c;首先定义一个校验接口&#xff0c;并提供一个校验方法&#xff1b;每种参数校验都是实现 了该校验接口…

前端vue-实现富文本组件

1.使用wangeditor富文本编辑器 工具网站&#xff1a;https://www.wangeditor.com/v4/ 下载安装命令&#xff1a;npm i wangeditor --save 成品如下图&#xff1a; 组件实现代码 <template><div><!-- 富文本编辑器 --><div id"wangeditor">…

Recbole安装指南:步骤详解与常见问题解决方案

1.两种方式&#xff1a; 从Conda安装 如果你还没有安装Conda&#xff0c;可以安装Miniconda或完整的Anaconda。 如果你在中国大陆&#xff0c;我们推荐你使用清华镜像安装Conda。 当你完成Conda的安装后&#xff0c;你可以将RecBole安装在python 3.7的Conda环境中&#xff0…

数据结构之树(下),你真的懂吗?

数据结构入门学习&#xff08;全是干货&#xff09;——树&#xff08;下&#xff09; 1 堆 (Heap) 1.1 什么是堆 堆 (Heap) 是一种特殊的完全二叉树&#xff0c;分为最大堆和最小堆。 最大堆&#xff1a;每个节点的值都大于或等于其子节点的值&#xff0c;根节点是整个堆的…

YOLOv9改进策略【注意力机制篇】| MCAttention 多尺度交叉轴注意力

一、本文介绍 本文记录的是基于MCA注意力模块的YOLOv9目标检测改进方法研究。普通的轴向注意力难以实现长距离交互&#xff0c;不利于捕获分割任务中所需的空间结构或形状&#xff0c;而MCA注意力模块通过构建了两个并行轴向注意力之间的交互&#xff0c;更有效地利用多尺度特…

2.4 卷积2

2.4.2 复正弦波与整体方案 在2.3节中&#xff0c;我们提出了关于复正弦输入的频域输出及其意义的两个问题。为了研究这些问题&#xff0c;我们让一个具有真实脉冲响应 h [ n ] h[n] h[n]&#xff08;即 h Q [ n ] 0 h_Q[n] 0 hQ​[n]0&#xff09;的LTI系统通过输入复正弦…

数据结构(Day16)

一、学习内容 1、有关顺序表的操作&#xff08;功能函数&#xff09; 1、创建顺序表 Plist create_list(){Plist L malloc(sizeof(list)); // 为顺序表分配内存空间if(NULL L){printf("申请空间失败\n");return NULL; // 如果内存分配失败&#xff0c;返回 NU…

RTMP协议在无人机巡检中的应用场景

为什么要用无人机巡检 好多开发者对无人机巡检技术方案&#xff0c;相对陌生&#xff0c;实际上&#xff0c;无人机巡检就是利用无人机对特定区域或设施进行定期或不定期的检查。这种巡检方式相比传统的人工巡检具有显著的优势&#xff0c;包括速度快、覆盖广、风险低、准确性…

Tornado 是一个 Python 异步网络库和 web 框架

Tornado 是一个 Python 异步网络库和 web 框架&#xff0c;它最初由 FriendFeed 开发&#xff0c;后来被 Facebook 收购并开源。Tornado 因其非阻塞的 I/O 操作和优秀的性能而广受欢迎&#xff0c;特别是在需要处理大量并发连接的应用中。Tornado 的底层实现主要依赖于 Python …

神经网络通俗理解学习笔记(0) numpy、matplotlib

Numpy numpynumpy 基本介绍Ndarray对象及其创建Numpy数组的基础索引numpy数组的合并与拆分&#xff08;重要&#xff09;numpy数组的矩阵运算Numpy数组的统计运算numpy中的arg运算numpy中的神奇索引和比较 Matplotlib numpy numpy 基本介绍 numpy 大多数机器学习库都用了这个…

【Linux入门】基本指令(一)

目录 一.使用环境 二.快捷键 三. 登录与用户管理 1.ssh root[ip地址] 2.whoami 3.ls /home 4.adduser [用户名] 5.passwd [用户名] 四.目录文件操作 1.ls 2.pwd 3.cd 4.touch 5.mkdir 6.rm 7.cp 五.命令手册 一.使用环境 云服务器&#xff1a;市面上有很多&am…

Python 中的 typing 模块常见用法

typing 模块是 Python 提供的一个标准库&#xff0c;主要用于为函数、变量和类定义类型提示&#xff08;Type Hints&#xff09;&#xff0c;从而提高代码的可读性和类型安全性。虽然 Python 是动态类型语言&#xff0c;但通过 typing 模块&#xff0c;开发者可以明确指定变量和…

TMStarget学习——Functional Connectivity

今天基于结构像和功能像数据试验操作TMStarget 的第二个功能模块Functional Connectivity。参考季老师的文档PPT来学习的&#xff0c;整个处理过程蛮长的&#xff0c;可能配置原因一路上报错也比较多&#xff0c;下面还是逐步记录吧&#xff0c;后面采用连更的方式直到跑通后再…

C++ 中的继承(详细讲解)

一、继承的概念以及定义 1、继承概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的…