Vue-Router 官网速通(上)

简介: Vue-Router 官网速通(上)

一:介绍

1. 什么是 Vue Router

是 Vue.js 的官方路由。功能包括:1. 路由映射。2. 动态路由。3. 路由配置。4. 路由参数。5. 过渡效果。6. 导航控制。7. CSS 类链接。8. HTML5 模式。9. 滚动行为。10. URL 编码

2. 安装

对于一个现有使用 JS 包管理的项目,添加 Vue Router 依赖:

npm install vue-router@4
# or
yarn add vue-router@4
# or
pnpm add vue-router@4

通过 create-vue 脚手架创建一个基于 Vite 的新项目,加入 Vue Router 的选项:

npm create vue@latest
# or
yarn create vue
# or
pnpm create vue

二:基础

1. 入门

router-view 显示与 URL 对应的组件。可以放在任何地方,以适应布局。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="https://unpkg.com/vue@3"></script>
    <script src="https://unpkg.com/vue-router@4"></script>
 
    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!--使用 router-link 组件进行导航 -->
        <!--通过传递 `to` 来指定链接 -->
        <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
        <router-link to="/">Go to Home</router-link>
        <router-link to="/about">Go to About</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
  </body>
  <script>
    // 1. 定义路由组件.
    const Home = { template: "<div>Home</div>" };
    const About = { template: "<div>About</div>" };
 
    // 2. 定义一些路由
    // 每个路由映射一个组件。
    const routes = [
      { path: "/", component: Home },
      { path: "/about", component: About },
    ];
 
    // 3. 创建路由实例并传递 `routes` 配置
    // 可以在这里输入更多的配置
    const router = VueRouter.createRouter({
      // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
      history: VueRouter.createWebHashHistory(),
      routes, // `routes: routes` 的缩写
    });
 
    // 5. 创建并挂载根实例
    const app = Vue.createApp({});
    //确保 _use_ 路由实例使
    //整个应用支持路由。
    app.use(router);
 
    app.mount("#app");
  </script>
</html>

在 Vue3 中通过调用 useRouter 和 useRoute 函数创建实例来访问。

<script setup lang="ts">
  import { useRouter, useRoute } from "vue-router";
 
  const router = useRouter();
  const route = useRoute();
 
  router.push("/"); // 跳转
  route.params; // 参数
</script>

2. 动态路由匹配

多个匹配路由映射到同一组件,通过一个动态字段来实现,称之为路径参数,路径参数用冒号 : 表示。如下 /users/johnny 和 /users/jolyne 会映射到同一个路由。

const User = {
  template: "<div>User</div>",
};
 
// 这些都会传递给 `createRouter`
const routes = [
  // 动态字段以冒号开始
  { path: "/users/:id", component: User },
];

通过 this.$route.params 来访问 URL 上的参数:

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

路由可以设置多个参数,在 $route.params 上相对应:

const User = {
  template: "<div>User</div>",
};
 
// 传递给 `createRouter`
const routes = [
  // 动态字段以冒号开始
  { path: "/users/:username/posts/:postId", component: User },
];
 
// 匹配路由:/users/eduardo/posts/123
// $route.params:{ username: 'eduardo', postId: '123' }

2.1 响应路由参数的变化

同一路由的不同参数跳转,因为映射的是相同组件,所以复用组件显得更高效,但生命周期函数就不会被调用,比如从 /users/johnny 导航到 /users/jolyne。要对同一路由的参数做出响应,需要用 watch 监听:

// vue3
import { watchEffect } from "vue";
watchEffect(() => {
  console.log(1, route.params, route.query);
});

2.2 捕获所有路由或 404 Not found 路由

想匹配任意路径,使用路径参数正则表达式,在路径参数后面的括号中加入正则表达式 :

const routes = [
  // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
  { path: "/:pathMatch(.*)*", name: "NotFound", component: NotFound },
  // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
  { path: "/user-:afterUser(.*)", component: UserGeneric },
];

3. 路由的匹配语法

大多数应用都会使用 /about 静态路由和 /users/:userId 动态路由,但是 Vue Router 提供了更多的方式!

3.1 在参数中自定义正则

两个路由 /:orderId 和 /:productName,会匹配完全相同的 URL,需要一种方法来区分他们,最简单的方法是添加一个静态部分来区分:

const routes = [
  // 匹配 /o/3549
  { path: "/o/:orderId" },
  // 匹配 /p/books
  { path: "/p/:productName" },
];

如果不想添加静态部分,也可以添加正则,orderId 总是一个数字,productName 可以是任何东西。以在括号中为参数指定正则,现在,/25 将匹配 /:orderId,其他情况匹配 /:productName。

const routes = [
  // /:orderId -> 仅匹配数字
  { path: "/:orderId(\\d+)" },
  // /:productName -> 匹配其他任何内容
  { path: "/:productName" },
];

TIP:确保转义反斜杠( \ ),就像对 \d (变成\\d)所做的那样,在 JS 中实际传递字符串中的反斜杠字符。

3.2 可重复的参数

匹配 /first/second/third 路由,应该用 \*(0 个或多个)和 +(1 个或多个)将参数标记为可重复:

const routes = [
  // /:chapters ->  匹配 /one, /one/two, /one/two/three, 等
  { path: "/:chapters+" },
  // /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等
  { path: "/:chapters*" },
];

提供了参数数组,而不是字符串,并且在使用命名路由时也需要你传递一个数组:

// 给定 { path: '/:chapters*', name: 'chapters' },
router.resolve({ name: "chapters", params: { chapters: [] } }).href;
// 产生 /
router.resolve({ name: "chapters", params: { chapters: ["a", "b"] } }).href;
// 产生 /a/b
 
// 给定 { path: '/:chapters+', name: 'chapters' },
router.resolve({ name: "chapters", params: { chapters: [] } }).href;
// 抛出错误,因为 `chapters` 为空

可以与正则结合使用:

const routes = [
  // 仅匹配数字
  // 匹配 /1, /1/2, 等
  { path: "/:chapters(\\d+)+" },
  // 匹配 /, /1, /1/2, 等
  { path: "/:chapters(\\d+)*" },
];

3.3 Sensitive 与 strict 路由配置

默认情况下,所有路由是不区分大小写和带尾部斜线的路由的。例如,路由 /users 将匹配 /users、/users/、/Users/。通过 strict 和 sensitive 选项来修改。

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 将匹配 /users/posva 而非:
    // - /users/posva/ 当 strict: true,尾部不能有斜线
    // - /Users/posva 当 sensitive: true,路由区分大小写
    { path: "/users/:id", sensitive: true },
    // 将匹配 /users, /Users, 以及 /users/42 而非 /users/ 或 /users/42/
    { path: "/users/:id?" },
  ],
  strict: true, // applies to all routes
});

3.4 可选参数

通过使用 ? 修饰符(0 个或 1 个)将一个参数标为可选:

const routes = [
  // 匹配 /users 和 /users/posva
  { path: "/users/:userId?" },
  // 匹配 /users 和 /users/42
  { path: "/users/:userId(\\d+)?" },
];

4. 嵌套路由

顶层的 router-view 渲染顶层路由匹配的组件。一个被渲染的组件也可以包含嵌套的 :

const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `,
};

要将组件渲染到嵌套的 router-view 中,需要在路由中配置 children,以 / 开头的嵌套路径将被视为根路径。不必使用嵌套的 URL:

const routes = [
  {
    path: "/user/:id",
    component: User,
    children: [
      {
        // 当 /user/:id/profile 匹配成功
        // UserProfile 将被渲染到 User 的 <router-view> 内部
        path: "profile",
        component: UserProfile,
      },
      {
        // 当 /posts 匹配成功
        // UserPosts 将被渲染到 User 的 <router-view> 内部
        path: "/posts",
        component: UserPosts,
      },
    ],
  },
];

如上配置,访问 /user/eduardo ,User 的 router-view 什么都不展示,因为没有匹配到嵌套路由。可以提供一个空的嵌套路径,来展示一些东西:

const routes = [
  {
    path: "/user/:id",
    component: User,
    children: [
      // 当 /user/:id 匹配成功
      // UserHome 将被渲染到 User 的 <router-view> 内部
      { path: "", component: UserHome },
 
      // ...其他子路由
    ],
  },
];

5. 编程式导航

除了  定义导航链接,还可以使用 router 的实例方法来导航。router.push 返回的是 Promise。

5.1 router.push 导航

使用 router.push 方法,会向 history 栈添加一个新的记录,所以,当点击浏览器后退按钮时,会回到之前的 URL。当点击  时,内部会调用这个方法,所以点击  相当于调用 router.push(...) :

// 字符串路径
router.push("/users/eduardo");
 
// 带有路径的对象
router.push({ path: "/users/eduardo" });
 
// 如果路由没有命名username参数,会报错,path: /user/:username?
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" });

使用 path 跳转 params 参数会无效,query 参数适用 path 或 name 跳转:

const username = "eduardo";
router.push(`/user/${username}`); // -> /user/eduardo
router.push({ path: `/user/${username}` }); // -> /user/eduardo
router.push({ name: "user", params: { username } }); // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: "/user", params: { username } }); // -> /user

5.2 替换当前位置

不会向 history 添加新记录,直接取代了当前的路由。用法:

<script setup lang="ts">
import { useRouter } from "vue-router";
 
const router = useRouter();
router.push({ path: "/home", replace: true });
// 相当于
router.replace({ path: "/home" });
</script>
 
<template>
  <router-link :to="..." replace>
</template>

5.3 横跨历史

router.go(n) 用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)。

// 向前移动一条记录,与 router.forward() 相同
router.go(1);
 
// 返回一条记录,与 router.back() 相同
router.go(-1);
 
// 前进 3 条记录
router.go(3);
 
// 如果没有那么多记录,静默失败
router.go(-100);
router.go(100);

6. 命名路由

使用 name 命名路由。优点:1. 没有硬编码的 URL。2. params 的自动编码/解码。3. 防止你在 url 中出现打字错误。4. 绕过路径排序(如显示一个)。

const routes = [
  {
    path: "/user/:username",
    name: "user",
    component: User,
  },
];

命名路由,通过 params 传递路由参数,如下路由将导航到 /user/erina。

<script setup lang="ts">
import { useRouter } from "vue-router";
 
const router = useRouter();
 
const handleGo = () =>
  router.push({ name: "user", params: { username: "erina" } });
</script>
 
<template>
  <router-link :to="{ name: 'user', params: { username: 'erina' } }">
    User
  </router-link>
  <div class="home" @click="handleGo">home</div>
</template>

7. 命名视图

设置多个同级,通过 name 属性确定渲染组件,默认 default:

<router-view class="view left-sidebar" name="LeftSidebar"></router-view>
<router-view class="view main-content"></router-view>
<router-view class="view right-sidebar" name="RightSidebar"></router-view>

多个视图就需要多个组件。正确配置 components (带上 s):

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: "/",
      components: {
        default: Home,
        // LeftSidebar: LeftSidebar 的缩写
        LeftSidebar,
        // 它们与 `<router-view>` 上的 `name` 属性匹配
        RightSidebar,
      },
    },
  ],
});

8. 重定向和别名

8.1 重定向

通过配置 redirect,实现路由重定向,当有 redirect 属性时,可以省略 component ,因为没有被访问,如下从 /home 重定向到 /:

const routes = [{ path: "/home", redirect: "/" }];

也可以使用 name 重定向:

const routes = [{ path: "/home", redirect: { name: "homepage" } }];

使用一个方法,动态返回重定向目标:

const routes = [
  {
    // /search/screens -> /search?q=screens
    path: "/search/:searchText",
    redirect: (to) => {
      // 方法接收目标路由作为参数
      // return 重定向的字符串路径/路径对象
      return { path: "/search", query: { q: to.params.searchText } };
    },
  },
  {
    path: "/search",
    // ...
  },
];

8.2 别名

访问别名和访问路由一个效果,使用 alias 声明别名,以 / 开头,并可以使用数组提供多个别名:

const routes = [
  {
    path: "/",
    component: Homepage,
    alias: "/home",
  },
  {
    path: "/users",
    component: UsersLayout,
    children: [
      // 为这 3 个 URL 呈现 UserList
      // - /users
      // - /users/list
      // - /people
      { path: "", component: UserList, alias: ["/people", "list"] },
    ],
  },
];

9. 路由组件传参

在组件中使用 $route 会与路由紧密耦合,限制了组件的灵活性,因为它只能用于特定的 URL。可以通过 props 配置来解除这种行为:

const User = {
  template: "<div>User {{ $route.params.id }}</div>",
};
const routes = [{ path: "/user/:id", component: User }];
 
// 替换成
const User = {
  // 请确保添加一个与路由参数完全相同的 prop 名
  props: ["id"],
  template: "<div>User {{ id }}</div>",
};
const routes = [{ path: "/user/:id", component: User, props: true }];

9.1 命名视图

对于有命名视图的路由,必须为每个命名视图定义 props 配置:

const routes = [
  {
    path: "/user/:id",
    components: { default: User, sidebar: Sidebar },
    props: { default: true, sidebar: false },
  },
];

9.2 函数模式

创建一个返回 props 的函数。可以将参数转换为其他类型:

const routes = [
  {
    path: "/demo/:id?",
    name: "demo",
    component: Demo,
    props: (route) => {
      return { id: +route.params.id };
    },
  },
];

9.3 Via RouterView

<RouterView v-slot="{ Component }">
  <component
    :is="Component"
    view-prop="value"
   />
</RouterView>

10. 不同的历史模式

在创建路由器实例时,history 配置可以选择不同的历史模式。

10.1 Hash 模式

hash 模式是用 createWebHashHistory() 创建的,会在 url 后添加哈希字符(#),对 SEO 不友好,不推荐:

import { createRouter, createWebHashHistory } from "vue-router";
 
const router = createRouter({
  // /home#/
  history: createWebHashHistory(),
  routes: [
    //...
  ],
});

10.2 Memory 模式

Memory 模式是用 createMemoryHistory() 创建的,适合 Node 环境和 SSR,不推荐:

import { createRouter, createMemoryHistory } from "vue-router";
const router = createRouter({
  history: createMemoryHistory(),
  routes: [
    //...
  ],
});

10.3 HTML5 模式

用 createWebHistory() 创建 HTML5 模式,URL 会看起来很 "正常",推荐使用这个模式:

import { createRouter, createWebHistory } from "vue-router";
 
const router = createRouter({
  history: createWebHistory(),
  routes: [
    //...
  ],
});

Vue-Router 官网速通(下)https://developer.aliyun.com/article/1513245?spm=a2c6h.13148508.setting.26.f8774f0euyBLtl

目录
相关文章
|
4月前
|
前端开发 JavaScript Java
React 速通笔记
【7月更文挑战第17天】
49 1
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的太原学院在线考试系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的太原学院在线考试系统附带文章源码部署视频讲解等
25 1
|
6月前
|
前端开发
SASS 官方文档速通
SASS 官方文档速通
38 1
|
6月前
|
JavaScript 前端开发 API
Vue-Router 官网速通(下)
Vue-Router 官网速通(下)
27 0
|
6月前
|
存储 JavaScript API
Pinia 官网速通
Pinia 官网速通
40 0
|
6月前
|
JSON JavaScript 前端开发
axios 官网速通
axios 官网速通
46 0
|
6月前
|
存储 JSON 缓存
Vite 官方文档速通(下)
Vite 官方文档速通(下)
97 0
|
6月前
|
JSON 前端开发 JavaScript
Vite 官方文档速通(上)
Vite 官方文档速通(上)
93 0
|
6月前
|
缓存 JavaScript 前端开发
Vue3 官方文档速通(上)
Vue3 官方文档速通(上)
244 0
|
6月前
|
JavaScript 前端开发 安全
Vue3官方文档速通(下)
Vue3官方文档速通(下)
95 0