【vue2】路由之 Vue Router

news2024/11/20 18:38:42

文章目录

  • 一、安装
  • 二、基础使用
    • 1、简单的示例
    • 2、动态路由
      • 2.1 定义动态路径参数
      • 2.2 获取动态路径的参数
      • 2.3 捕获所有路由
    • 3、嵌套路由
    • 4、编程式的导航
      • 4.1 router.push
      • 4.2 router.replace
      • 4.3 router.go(n)
    • 5、命名路由
    • 6、重定向
  • 三、进阶
    • 1、导航守卫
      • 1.1 全局前置守卫
      • 1.2 全局后置钩子
      • 1.3 路由独享的守卫
      • 1.4 组件内的守卫
      • 完整的导航解析流程
    • 2、路由懒加载

一、安装

NPM
注意:vue2中需使用 v.3x 版本

npm install vue-router@3.0.0 --save

vue-router v3.x 文档:文档链接

二、基础使用

1、简单的示例

src/main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = {
  template: '<div>Foo</div>'
}
const Bar = {
  template: '<div>Bar</div>'
}

// 2. 定义路由
// 每个路由应该映射一个组件
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
  routes
})

// 4. 通过 Vue.use() 明确地安装路由功能
Vue.use(VueRouter);

// 5. 创建和挂载根实例。
// 通过 router 配置参数注入路由,让整个应用都有路由功能
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

src/App.vue

<template>
  <div id="app">
    <p>
      <!-- 使用 router-link 组件来导航. -->
      <!-- 通过传入 `to` 属性指定链接. -->
      <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
      <router-link to="/foo">Foo</router-link><br />
      <router-link to="/bar">Bar</router-link>
    </p>
    <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
};
</script>

2、动态路由

2.1 定义动态路径参数

动态路径参数以冒号开头

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})

现在像 /user/123 和 /user/456 都将映射到相同的路由

2.2 获取动态路径的参数

当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

可以通过 $route.params 查看所有的参数信息
$route 对象还提供了其它有用的信息

const User = {
  template: '<div>User {{ $route.params.id }}</div>',
  created: function () {
    console.log(this.$route)
  }
}

当路由是 /user/101 时,$route 示例:
在这里插入图片描述

2.3 捕获所有路由

可以使用通配符 (*):

{
  // 会匹配所有路径
  path: '*'
}
{
  // 会匹配以 `/user-` 开头的任意路径
  path: '/user-*'
}

3、嵌套路由

要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:
src/main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

import UserView from './components/UserView.vue'
import FooView from './components/FooView.vue'
import BarView from './components/BarView.vue'

const routes = [
  {
    path: '/user',
    component: UserView,
    children: [
      {
        // 当 /user/foo 匹配成功,
        // FooView 会被渲染在 User 的 <router-view> 中
        path: 'foo',
        component: FooView
      },
      {
        // 当 /user/bar 匹配成功,
        // BarView 会被渲染在 User 的 <router-view> 中
        path: 'bar',
        component: BarView
      },
    ]
  },
]

const router = new VueRouter({
  routes
})

Vue.use(VueRouter);

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

顶层 <router-view> 出口,App.vue

<template>
  <div id="app">
    <p>
      <router-link to="/user/foo">Foo</router-link><br />
      <router-link to="/user/bar">Bar</router-link><br />
    </p>
    <!-- 这个是顶层的 router-view -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
};
</script>

组件同样可以包含自己的嵌套 <router-view>
组件 UserView.vue

<template>
  <div class="user">
    <h2>User</h2>
    <router-view></router-view>
  </div>
</template>

组件 BarView.vue

<template>
    <div>
        bar
    </div>
</template>

组件 FooView.vue

<template>
    <div>
        foo
    </div>
</template>

要注意,以 / 开头的嵌套路径会被当作根路径

4、编程式的导航

4.1 router.push

这个方法会向 history 栈添加一个新的记录
代码实现路由跳转:

router.push(location, onComplete?, onAbort?)
声明式编程式
<router-link :to="..." >router.push(...)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象,示例:

<template>
  <div id="app">
    <div>
      <button @click="routeUser">字符串跳转user</button>
      <button @click="routeFoo">对象跳转foo</button>
      <button @click="routeBarParams">对象跳转带参数Params</button>
      <button @click="routeBarQuery">对象跳转带参数Query</button>
    </div>
    <!-- 这个是顶层的 router-view -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
  methods: {
    routeUser() {
      // 字符串
      this.$router.push("/user");
    },
    routeFoo() {
      // 对象
      this.$router.push({path: "/foo"});
    },
    routeBarParams() {
      // 命名的路由(带name属性)
      this.$router.push({ name: 'bar', params: { id: '123' }})
    },
    routeBarQuery() {
      // 带查询参数,变成 /bar?id=456
      this.$router.push({ path: '/bar', query: { id: '456' }})
      
      // 注意:如果提供了 path,params 会被忽略
      // 下面的 params 不生效
	  // this.$router.push({ path: '/bar', params: { id }}) // -> /user
    },
  },
};
</script>

4.2 router.replace

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录

router.replace(location, onComplete?, onAbort?)
声明式编程式
<router-link :to="..." replace>router.replace(...)

4.3 router.go(n)

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

// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)

// 后退一步记录,等同于 history.back()
router.go(-1)

// 前进 3 步记录
router.go(3)

5、命名路由

可以在创建 Router 实例的时候,在 routes 配置中使用 name 给某个路由设置名称:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

6、重定向

重定向也是通过 routes 配置来完成,使用 redirect
下面例子是从 /a 重定向到 /b:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

三、进阶

1、导航守卫

1.1 全局前置守卫

使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

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

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
    • next(): 进行管道中的下一个钩子
    • next(false): 中断当前的导航
    • next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址

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

身份时重定向到 /login 的示例:

router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) {
  	next({ name: 'Login' })
  } else {
	next()
  }
})

1.2 全局后置钩子

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

router.afterEach((to, from) => {
  // ...
})

1.3 路由独享的守卫

可以在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

1.4 组件内的守卫

可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

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

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 10.调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入

2、路由懒加载

就是当路由被访问的时候才加载对应的组件
示例:

const Foo = () => import('./Foo.vue')

const router = new VueRouter({
  routes: [{ path: '/foo', component: Foo }]
})

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

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

相关文章

1Panel CloudFlare证书申请失败的解决方案

在升级1Panel后&#xff0c;使用 CloudFlare DNS验证时&#xff0c;会提示 [*.biliwind.com] [*.biliwind.com] acme: error presenting token: cloudflare: failed to find zone biliwind.com.: ListZonesContext command failed: Invalid request headers (6003) 为解决此问…

如何在Arxiv上预发表自己的手稿

1. 使用latex编辑好自己的手稿。可以使用latex软件或者overleaf。尽量避免警告&#xff0c;否则会在上传到arxiv时出现意外的错误。 2. https://arxiv.org/登陆并注册arxiv账号 3. 点击 开始新的提交&#xff08;START NEW SUBMISSION&#xff09; 4. 主要的问题是参考文献的导…

C++:auto 关键字 范围for

目录 auto 关键字&#xff1a; 起源&#xff1a; auto的使用细则&#xff1a; auto不能推导的场景&#xff1a; 范围for&#xff1a; 范围for的使用条件&#xff1a; C的空指针&#xff1a; 注意&#xff1a; auto 关键字&#xff1a; 起源&#xff1a; 随着程序越…

全角色服务、全场景支撑、全业务应用的新一代智慧教室

新一代智慧教室以“数智化助力高质量人才培养”为核心目标&#xff0c;以AI赋能的智能硬件为基础构建多形态智慧教学环境&#xff0c;以中台为支撑实现数据、设备、系统、业务的互联互通、开放共享&#xff0c;以平台全面覆盖教学应用&#xff0c;采集、汇聚、挖掘、分析课前课…

【周赛】第382场周赛

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 从这一场&#xff08;第382场周赛&#xff09;周赛开始记录&#xff0c;目标是尽快达到准确快速AC前三道题&#xff0c;每场比赛…

【服务器GPT+MJ+GPTs】创建部署GPT+MJ+GPTs程序网站

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建GPT+MJ+GPTs】 🌼1. 给服务器添加端口 🌼2. 安装宝塔 🌼3. 安装Docker 🌼4. 安装ChatGPT程序 🌼5. 程序更新 🌼6. 修改端口 | 密码 🌼7. 绑定域名+申请SSL证书 🌺【前言】 相信大家都对openai的产品ch…

【2024】Docker部署Redis

1.说明&#xff1a; 因为容器实例的运行是有生命周期的&#xff0c;一些redis的备份、日志和配置文件什么的最好还是放在服务器本地。这样当容器删除时&#xff0c;我们也可以保留备份和日志文件。所以先在本地服务器安装redis并配置文件设置。下面是安装步骤: 2.安装步骤 1…

Unity 命令模式(实例详解)

文章目录 示例1&#xff1a;基础命令类结构示例2&#xff1a;旋转对象命令示例3&#xff1a;增加道具命令示例4&#xff1a;切换场景命令示例5&#xff1a;播放音效命令 在Unity中使用命令模式&#xff08;Command Pattern&#xff09;是一种常见的设计模式&#xff0c;用于实现…

LeetCode344反转字符串(java实现)

今天我们来分享的题目是leetcode344反转字符串。题目描述如下&#xff1a; 我们观察题目发现&#xff0c;题目要求使用O(1)的空间解决这一问题。那么我们就不能进行使用开辟新的数组进行反转了。 解题思路&#xff1a;那么该题的我得思路是使用双指针的方法进行题解&#xff0…

深度强化学习(王树森)笔记01

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…

80.网游逆向分析与插件开发-背包的获取-自动化助手显示物品数据1

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;升级Notice类获得背包基址-CSDN博客 码云地址&#xff08;ui显示角色数据 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;3be017de38c50653b…

【算法专题】二分查找(进阶)

&#x1f4d1;前言 本文主要是二分查找&#xff08;进阶&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日…

【代码随想录】LC 242. 有效的字母异位词

文章目录 前言一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 前言 本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记&#xff0c;如有侵权&#xff0c;立即删除。 一、题目 1、原题链接 242. 有效的字母异位词 2、题目描述 二、解题…

【c++】类和对象 - 类的引入和定义

1.类的引入 C语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定义函数。比如&#xff1a;之前在数据结构初阶中&#xff0c;用C语言方式实现的栈&#xff0c;结构体中只能定义变量&#xff1b;现在以C方式实现&#xff0c;…

java日志框架总结(三 、Log4j日志框架)

一、简介 Log4j ( Logger For Java ) , Java 日志的记录包。 官方网站 。Log4j 是 Apache 的一个开源项目&#xff0c; 为Java提供了日志记录功能。能够让程序员非常方便的记录日志&#xff0c; 并且提供了多种适配方式&#xff0c;能满足各种需求。 使用Log4j 只需要导入一个…

linux0.11源码看信号的处理流程

序 日常Linux写代码或者使用中难免会使用siganl&#xff0c;包括我们使用ctrl-c结束程序&#xff0c;使用kill命令发送信号&#xff0c;或者说程序core后操作系统向程序发送的信号&#xff0c;以及我们程序内部自定义的信号处理。 我们选择linux0.11一个原因是它比较简单&…

基于springboot宠物领养系统

摘要 随着社会的不断发展和人们生活水平的提高&#xff0c;宠物在家庭中的地位逐渐上升&#xff0c;宠物领养成为一种流行的社会现象。为了更好地管理和促进宠物领养的过程&#xff0c;本文基于Spring Boot框架设计和实现了一套宠物领养系统。该系统以用户友好的界面为特点&…

游戏开发丨基于Tkinter的扫雷小游戏

文章目录 写在前面扫雷小游戏需求分析程序设计程序分析运行结果系列文章写在后面 写在前面 本期内容 基于tkinter的扫雷小游戏 所需环境 pythonpycharm或anaconda 下载地址 https://download.csdn.net/download/m0_68111267/88790713 扫雷小游戏 扫雷是一款广为人知的单…

【SpringSpringBoot】概述

Spring&SpringBoot专题 【注】&#xff1a; 本专题围绕框架核心概念展开&#xff0c;渐进式深入总结学习、面试、开发经验&#xff0c;集中整理便于回顾 持续补充与施工中~~~~ 1.发展史 2.基本架构 Spring框架的基本架构是一个分层架构&#xff0c;包括多个模块&#x…

漏洞原理反射型XSS漏洞

漏洞原理XSS漏洞 1 反射型XSS php基础链接 Web渗透编程语言基础-CSDN博客 正常思维 http://127.0.0.1/websec/day01/xss_reflect.php?name%E6%88%91%E6%98%AF%E8%B0%81 http://127.0.0.1/14_WEBSEC/DAY01/xss_reflect.php?name我是谁 黑客思维 http://127.0.0.1/websec…