Skip to content

编程式导航

编程式导航

简介

在 Vue.js 中,编程式导航是指使用 JS 代码来实现页面之间的切换或跳转,而不是依赖于用户的手动操作,例如点击链接或按钮。在 Vue 中,可以使用 Vue Router 提供的 router 对象来进行编程式导航。

页面导航的两种方式

页面导航有两种方式:声明式导航和编程式导航。

声明式导航即前边章节所介绍的<router-link :to="...">的写法,这种写法简单直观,代码量少也易于理解,适用于静态导航。

不足之处在于如若需要根据业务逻辑或用户交互来控制导航,可能显得不够灵活。并且也不能在方法中直接使用。

本节介绍的编程式导航灵活性高,并且适用于复杂的导航逻辑,可以在路由实例的方法中直接调用 router 对象的方法来进行导航。

它的优点是适用于根据具体业务逻辑动态控制导航的情况,灵活性更高,但可能需要编写更多的代码,可读性相比声明式会复杂些。

编程式导航用法

通过 router 对象,可以执行以下操作:

  1. 跳转到指定路由:使用 router.push() 方法可以将用户导航到指定的路由。
  2. 返回上一页:使用router.go() 方法可以在用户的历史记录中后退或前进。
  3. 获取当前路由信息:使用this.$router来访问当前的路由信息,包括路径、参数等。

router.push()

router.push()用于跳转到指定路由,和 <router-link> 的效果类似,区别在于,该方法会向 history 栈添加一个新的记录,用户可回退到之前的 URL。它接收如下参数类型:

  • 字符串路径。
  • 描述地址的对象。
  • 命名的路由(传递参数)。
  • 带查询参数。
  • 注意:params 不能与 path 一起使用。

在 Home 页面分别用点击实现实现上述的四种参数类型,示例代码如下所示:

Params.vue

<template>
    <div>
        <h1></h1>
        <!-- <p> 用户的 ID 是 {{ this.$route.params.userId }}</p> -->
        <!-- 因valor插件原因,提示工具会报错,但可以正常使用 -->
        <p> 用户的 UserID 是 {{ $route.params.userId }}</p>
    </div>
</template>

Search.vue

<template>
    <div>
      <h1>Search Results</h1>
      <p>搜索的内容是: {{ this.$route.query.q }}</p>
    </div>
</template>

CodeChild.vue

<template>
    <div>
      <h1>Code Child Page</h1>
    </div>
</template>

CodeHome.vue

<template>
    <div>
      <h1>Code Home Page</h1>
      <!-- 子页面出口 -->
      <router-view></router-view>
    </div>
</template>

Home.vue

<script setup>

    const toCodeHome = (router) => {
        // 使用 `router.push` 进行路由导航
        // 字符串路径
        router.push("/codehome");

    };

    const toCodeChild = (router) => {
        // 带有路径的对象
        router.push({ path: "/codehome/codechild" });
    };

    const toHomeNameWithParams = (router) => {
        // 命名的路由,并加上参数
        router.push({ name: "userWithParam", params: { userId: 123 } });
    };

    const searchSomething = (router) => {
        // 带查询参数
        router.push({ name: "search", query: { q: "今天吃什么" } });
    };
</script>
<template>
    <div>
      <h1>Home Page</h1>
      <p>
        <button @click="toCodeHome($router)">
          点击跳转到 toCodeHome 的路由地址
        </button>
      </p>
      <p>
        <button @click="toCodeChild($router)">
          点击跳转到 path 为 /codehome/codechild 的路由地址
        </button>
      </p>
      <p>
        <button @click="toHomeNameWithParams($router)">
          点击跳转到 name 为 userWithParam 且包含参数的路由地址
        </button>
      </p>
      <p>
        <button @click="searchSomething($router)">
          点击跳转到 name 为 search 且包含查询参数的路由地址
        </button>
      </p>
      <router-view></router-view>

    </div>
  </template>

index.js

iimport {createRouter, createWebHashHistory} from "vue-router"
import Params from "../views/Params.vue"
import Search from "../views/Search.vue"
import CodeHome from "../views/CodeHome.vue"
import CodeChild from "../views/CodeChild.vue"

// 创建一个路由关系表
const routers = [
    {
        path:'/codehome',
        component:CodeHome,
        // 设置多个别名
        children:[
            {
                path: "codechild",
                component: CodeChild,
                name: 'codechild',
            }
        ]
    },
    {
        path:'/search',
        name:'search',
        component:Search
    },
    {
        path:"/params/:userId",
        name:"userWithParam",
        component:Params
    }
]

// 创建路由对象
const router = createRouter({
    history:createWebHashHistory(),
    routes: routers
})

export default router

App.vue

<script setup>
import Home from "./views/Home.vue"
</script>

<template>
    <Home></Home>
</template>

router.go()

router.go(n) 是 Vue Router 提供的一个方法,它接收一个整数作为参数,用于在路由历史记录中前进或后退指定的步数。

例如,当前页面的路由历史记录如下:

1. /page1
2. /page2
3. /page3

假设当前处于 /page3 页面,如果你调用 router.go(-1) 或 router.back(),那么就会后退到 page2 页面。

反之,如果调用 router.go(1) 或 router.forward() ,那么就会前进到 /page3 后边的页面(如果有的话)。

使用示例如下:

Home.vue

<script setup>
const goFroward = (router) => {
  router.go(1);
};
const goBack = (router) => {
  router.go(-1);
};
</script>
<template>
  <div>
      <h1>Home Page</h1>
      <p><button @click="goFroward($router)">点击进入下一个页面</button></p>
      <p><button @click="goBack($router)">点击后退一页</button></p>
      <router-view></router-view>
  </div>
</template>

如果在路由历史记录中没有足够的步数来前进或后退,router.go(n) 将不会产生任何效果。

router.replace()

router.replace() 是 Vue Router 提供的一个方法,用于在不保留浏览历史记录的情况下进行路由导航。

router.push() 不同,router.replace() 会替换当前的路由历史记录,不会添加新的记录。也意味着在使用router.replace() 之后,用户无法通过浏览器的后退按钮返回到之前的页面。

语法如下所示:

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

代码示例如下所示:

Home.vue

<template>
    <div>
        <h1>Home Page</h1>
        <p><button @click="replaceNow($router)">替换路由到 Ceshiren 页面 </button></p>
    </div>
</template>
<script setup>
const replaceNow=(router)=>{
    router.replace("/ceshiren")
}
</script>

当进入到 CodeChild 页面时,点击替换路由按钮,这时会直接跳转到 ceshiren 页面,即进入 http://127.0.0.1:5173/#/ceshiren

总结

本节介绍的编程式导航可以实现页面间的跳转或切换,通过 router 对象提供的方法,可灵活地控制页面的导航行为,从而实现更好的用户体验。