Skip to content

编程式导航

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

导航到不同的位置

注意:在 Vue 实例中,你可以通过 $router 访问路由实例。因此你可以调用 $router.push

想要导航到不同的 URL,可以使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。

当你点击 <router-link> 时,内部会调用这个方法,所以点击 <router-link :to="..."> 相当于调用 router.push(...)

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

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

js
// 字符串路径
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.md#team
router.push({ path: "/about.md", hash: "#team" });

注意:如果提供了 pathparams 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path

js
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

当指定 params 时,可提供 stringnumber 参数(或者对于可重复的参数 可提供一个数组)。任何其他类型(如 undefinedfalse 等)都将被自动字符串化 。对于可选参数 ,你可以提供一个空字符串("")来跳过它。

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

替换当前位置

它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。

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

也可以直接在传递给 router.pushrouteLocation 中增加一个属性 replace: true

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

横跨历史

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

例子

js
// 向前移动一条记录,与 router.forward() 相同
router.go(1);

// 返回一条记录,与 router.back() 相同
router.go(-1);

// 前进 3 条记录
router.go(3);

// 如果没有那么多记录,静默失败
router.go(-100);
router.go(100);

命名路由

https://router.vuejs.org/zh/guide/essentials/named-routes.html

除了 path 之外,你还可以为任何路由提供 name。这有以下优点:

  • 没有硬编码的 URL
  • params 的自动编码/解码。
  • 防止你在 url 中出现打字错误。
  • 绕过路径排序(如显示一个)
js
const routes = [
  {
    path: "/user/:username",
    name: "user",
    component: User,
  },
];

要链接到一个命名的路由,可以向 router-link 组件的 to 属性传递一个对象:

vue
<router-link :to="{ name: 'user', params: { username: 'erina' } }">
User
</router-link>

这跟代码调用 router.push() 是一回事:

js
router.push({ name: "user", params: { username: "erina" } });

在这两种情况下,路由将导航到路径 /user/erina

完整的例子在这里.

编程式导航 - 案例

注意:先复制一份 router01 文件,在里面编辑修改

基础使用

语法:

js
router.push({
  path: "路由路径", // 都去 router/index.js 定义
  name: "路由名",
});

1、在 src/router/index.js - 路由数组里,给路由起名字

js
const routes = [
  {
    path: "/find",
    name: "Find",
    component: () => import("../views/Find.vue"),
  },
  {
    path: "/my",
    name: "My",
    component: () => import("../views/My.vue"),
  },
  {
    path: "/part",
    name: "Part",
    component: () => import("../views/Part.vue"),
  },
];

2、App.vue - 换成 span 配合 js 的编程式导航跳转

vue
<template>
  <div>
    <div class="footer_wrap">
      <a @click="change_router('/find', 'Find')">发现音乐</a>
      <a @click="change_router('/my', 'My')">我的音乐</a>
      <a @click="change_router('/part', 'Part')">朋友</a>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

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

const router = useRouter();

// 目标:编程式导航 - js 方式跳转路由
// 语法:
const change_router = (path, name) => {
  // router.push({path: "路由路径"})
  // router.push({name: "路由名"})
  // 注意:
  // 虽然用 name 跳转,但是 url 的 hash 值还是切换 path 路径值
  // 场景:
  // 方便修改:name 路由名 (在页面上看不见随便定义)
  // path 可以在 url 的 hash 值看到 (尽量符合组内规范)

  // router.push(path)
  // router.push({path: path})
  router.push({ name: name });
};
</script>

跳转传参

目标:JS 跳转路由,传参

语法 path / params 任选 一个

js
router.push({
    path: "路由路径"
    name: "路由名",
    query: {
        "参数名": 值
    }
    params: {
        "参数名": 值
    }
})

// 对应路由接收   route.params.参数名   取值
// 对应路由接收   route.query.参数名    取值

格外注意:使用 path 会自动忽略 params

在项目中添加 views/Part2.vue 组件,然后在路由表中添加

js
import { createRouter, createWebHistory } from "vue-router";

const routes = [
  // 省略之前的参数
  {
    path: "/part/:name",
    name: "Part2",
    component: () => import("../views/Part2.vue"),
  },
];

export const router = createRouter({
  history: createWebHistory(),
  routes: routes,
});

然后修改 App.vue

vue
<template>
  <div>
    <div class="footer_wrap">
      <a @click="change_router('/find', 'Find')">发现音乐</a>
      <a @click="change_router('/my', 'My')">我的音乐</a>
      <a @click="change_router('/part', 'Part')">朋友</a>
      <a @click="change1">朋友 - 小传</a>
      <a @click="change2">朋友 - 小智</a>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

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

const router = useRouter();

const change_router = (path, name) => {
  router.push({ name: name });
};

const change1 = () => {
  router.push({
    name: "Part2",
    params: {
      name: "小传",
    },
  });
};

const change2 = () => {
  router.push({
    name: "Part2",
    path: "小传",
    // params: {
    //   name: '小传'
    // },    query: {
  });
};
</script>

重定向

重定向也是通过 routes 配置来完成,下面例子是从 /home 重定向到 /

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

重定向的目标也可以是一个命名的路由:

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

甚至是一个方法,动态返回重定向目标:

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

例如:网页默认打开,匹配路由 "/", 强制切换到 "/find"

js
const routes = [
  {
    path: "/", // 默认 hash 值路径
    redirect: "/find", // 重定向到 /find
    // 浏览器 url 中 # 后的路径被改变成 /find -重新匹配数组规则
  },
];

总结:强制重定向后,还会重新来数组里匹配一次规则