vue-router(vue 路由)基本使用指南(一)

vue-router(vue 路由)基本使用指南(一)

概述

客户端 vs 服务端路由

  • 服务端路由

    服务器根据用户访问的 URL 路径返回不同的响应结果。当在一个传统的服务端渲染的 web 应用中点击一个链接时,浏览器会从服务端获得全新的 HTML,然后重新加载整个页面。

  • 客户端路由

    在单页面应用中,客户端的 JavaScript 可以拦截页面的跳转请求,动态获取新的数据,然后在无需重新加载的情况下更新当前页面。这样通常可以带来更顺滑的用户体验,尤其是在更偏向“应用”的场景下,因为这类场景下用户通常会在很长的一段时间中做出多次交互。

    在这类单页应用中,“路由”是在客户端执行的。一个客户端路由器的职责就是利用诸如 History API 或是 hashchange 事件这样的浏览器 API 来管理应用当前应该渲染的视图。

    客户端路由的作用是在单页应用 (SPA) 中将浏览器的 URL 和用户看到的内容绑定起来。当用户在应用中浏览不同页面时,URL 会随之更新,但页面不需要从服务器重新加载。


Vue Router 介绍

Vue Router 是 Vue 官方的客户端路由解决方案,与 Vue.js 核心深度集成,用于构建单页面应用(SPA)。

Vue Router 基于 Vue 的组件系统构建,可以通过配置路由来告诉 Vue Router 为每个 URL 路径显示哪些组件。

功能包括:

  • 嵌套路由映射
  • 动态路由选择
  • 模块化、基于组件的路由配置
  • 路由参数、查询、通配符
  • 展示由 Vue.js 的过渡系统提供的过渡效果
  • 细致的导航控制
  • 自动激活 CSS 类的链接
  • HTML5 history 模式或 hash 模式
  • 可定制的滚动行为
  • URL 的正确编码

Vue Router 基础概念

  • 路由器(router):管理所有路由的中央控制器

    功能包括:

    • 监听URL的变化
    • 根据定义的 路由规则,映射到对应的组件。
    • 提供导航方法,控制页面跳转。
  • 路由(route):表示一个 URL 与组件的映射关系

    一个典型的路由定义包括:

    • path:URL当中的路径部分
    • ***pontent:当路径匹配时要渲染的组件
  • 路由视图 (<router-view>):一个占位组件,告诉 Vue Router 在这里渲染匹配到的组件。

  • 路由链接 (<router-link>):声明式的导航组件(替代传统的 <a> 标签)

    用于创建导航链接,点击后会改变 URL,并触发路由跳转(不会触发页面刷新,只更新匹配的组件)


快速入门

安装 Vue Router

安装 Vue Router

  • 对于一个现有的使用 JavaScript 包管理器的项目,可以从 npm registry 中安装 Vue Router:

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

    以上命令三选一

  • 如果打算启动一个新项目,使用 create-vue 这个脚手架工具更容易,它能创建一个基于 Vite 的项目,并包含加入 Vue Router 的选项:

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

    以上命令三选一


创建路由器实例

路由器实例是通过调用 createRouter() 函数创建:

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

const router = createRouter({
    history: createWebHistory(),
    routes = [
    	{ path: '/', ***ponent: HomeView },
		{ path: '/about', ***ponent: () => import('./AboutView.vue') },
    ],
})
  • routes 选项:定义了一组路由,把 URL 路径映射到组件。

  • ***ponent 参数:指定组件,这些路由组件通常被称为视图,但本质上它们只是普通的 Vue 组件。

    其他可以设置的路由选项后面介绍,基础的只需要 path***ponent

  • history 选项:控制路由和 URL 路径是如何双向映射的。

    常用 createWebHistory()createWebHashHistory()


注册路由器插件

一旦创建了路由器实例,就需要将其注册为插件,这一步骤可以通过调用 use() 来完成。

main.js

createApp(App).use(router).mount('#app')

// 或等价地:

const app = createApp(App)
app.use(router)
app.mount('#app')
  • 和大多数的 Vue 插件一样,use() 需要在 mount() 之前调用。
  • use(router) 插件的职责包括:
    • 全局注册 RouterView 和 RouterLink 组件。
    • 添加全局 $router$route 属性。
    • 启用 useRouter()useRoute() 组合式函数。
    • 触发路由器解析初始路由。

使用路由组件

App.vue

<template>
  <h1>Hello App!</h1>
  <p><strong>Current route path:</strong> {{ $route.fullPath }}</p>

  <nav>
    <RouterLink to="/">Go to Home</RouterLink>
    <RouterLink to="/about">Go to About</RouterLink>
  </nav>

  <main>
    <RouterView />
  </main>
</template>

在这个 template 中使用了两个由 Vue Router 提供的组件: RouterLinkRouterView

  • RouterLink 组件:不同于常规的 <a> 标签,使用组件 RouterLink 创建链接使得 Vue Router 能够在不重新加载页面的情况下改变 URL,处理 URL 的生成、编码和其他功能。

  • RouterView 组件:使 Vue Router 知道在哪里渲染当前 URL 路径对应的路由组件

    它不一定要在 App.vue 中,可以把它放在任何地方,但它需要在某处被导入,否则 Vue Router 就不会渲染任何东西。

  • $route :在组件模板中可使用的当前的路由对象。


访问路由器和当前路由

如果是从 ES 模块导出路由器实例的,则可以将路由器实例直接导入到需要它的地方。在一些情况下这是最好的方法,但如果在组件内部,那么还有其他选择。

  • 选项式 API 中,可以在 JavaScript 中如下访问这两个属性:this.$routerthis.$route

    export default {
      methods: {
        goToAbout() {
          this.$router.push('/about')
        },
      },
    }
    
  • 组合式 API 中,不能通过 this 访问组件实例,而是使用 Vue Router 提供的 useRouter()useRoute() 来访问路由器实例和当前路由。

    <script setup>
    import { ***puted } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    
    const router = useRouter()
    const route = useRoute()
    
    const search = ***puted({
      get() {
        return route.query.search ?? ''
      },
      set(search) {
        router.replace({ query: { search } })
      },
    })
    </script>
    

基础

懒加载路由

通过动态导入实现路由组件的懒加载:

const routes = [
  {
    path: '/about',
    ***ponent: () => import('./***ponents/About.vue'),
  },
];

命名路由

当创建一个路由时,我们可以选择给路由一个 name,然后可以使用 name 而不是 path 来传递 to 属性。

所有路由的命名都必须是唯一的。如果为多条路由添加相同的命名,路由器只会保留最后那一条。

  • 路由配置

    const routes = [
      {
        path: '/user/:id',
        name: 'user',	// 命名路由
        ***ponent: User,
      },
    ];
    
  • 导航到命名路由

    this.$router.push({ name: 'user', params: { id: 123 } });
    

使用 name 的优点

  • 没有硬编码的 URL。
  • params 的自动编码/解码。
  • 防止你在 URL 中出现打字错误。
  • 绕过路径排序,例如展示一个匹配相同路径但排序较低的路由。

命名视图

可以在界面中拥有多个单独命名的视图(同时 /同级展示多个视图,而不是嵌套展示),而不是只有一个单独的出口。

例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,如果 router-view 没有设置名字,那么默认为 default

  • 路由配置

    const routes = [
        {
            path: '/views',
            ***ponents: {
                default: ViewMain, 		// 默认视图绑定的组件
                sidebar: ViewSidebar,	// 命名视图绑定的组件。若视图名和组件名相同,可以缩写为:ViewSidebar,
            },
        },
    ];
    
  • 组件模板

    <template>
        <router-view></router-view>					<!-- 默认视图 -->
        <router-view name="sidebar"></router-view>	<!-- 命名视图 -->
    </template>
    

嵌套命名视图

若想使用命名视图创建嵌套视图的复杂布局,也需要命名用到的嵌套 router-view 组件

  • 路由配置

    {
        path: '/settings',
        // 也可以在顶级路由就配置命名视图
        ***ponent: UserSettings,
        children: [
            {
                path: 'emails',
                ***ponent: UserEmailsSubscriptions
            }, 
            {
                path: 'profile',
                ***ponents: {
                    default: UserProfile,
                    helper: UserProfilePreview
                }
            }
        ]
    }
    
  • 组件模板

    <!-- UserSettings.vue -->
    <div>
        <h1>User Settings</h1>
        <NavBar />
        <router-view />
        <router-view name="helper" />
    </div>
    
    • Nav 只是一个常规组件。
    • UserSettings 是一个视图组件。
    • UserEmailsSubscriptionsUserProfileUserProfilePreview 是嵌套的视图组件。

编程式导航

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

在组件内部,获取路由器实例

  • 选项式 API:使用 $router 属性访问路由器,例如 this.$router.push(...)
  • 组合式 API:通过调用 useRouter() 方法获取路由器实例。

router.push():导航到不同的 URL

该方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。

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

方法的参数:

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

    // 字符串路径
    router.push('/users/eduardo')
    // 带有路径的对象
    router.push({ path: '/users/eduardo' })
    // 带查询参数,结果是 /register?plan=private
    router.push({ path: '/register', query: { plan: 'private' } })
    // 带 hash,结果是 /about#team
    router.push({ path: '/about', hash: '#team' })
    // 命名的路由,并加上参数,让路由建立 url
    router.push({ name: 'user', params: { username: 'eduardo' } })
    

    注意

    • params 不能与 path 一起使用。如果提供了 path,则 params 会被忽略。如果非要使用 path,则需要直接将 params 的值填充进 path 中:

      const username = 'eduardo'
      // 手动建立 url,但必须自己处理编码
      router.push(`/user/${username}`) // -> /user/eduardo
      router.push({ path: `/user/${username}` }) // -> /user/eduardo
      
    • 当指定 params 时,可提供 stringnumber 参数(或者对于可重复的参数可提供一个数组)。

      任何其他类型(如对象、布尔等)都将被自动字符串化。

    • 对于可选参数,可以提供一个空字符串(“”)或 null 来移除它。

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


router.replace():替换当前位置

该方法的作用类似于 router.push(),唯一不同的是,它在导航时不会向 history 添加新记录,它取代了当前的条目。

  • 也可以直接在传递给 router.push()to 参数中增加一个属性 replace: true

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

router.go():前进或后退多少步

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

  • 示例:

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

路由传参

在 Vue 3 应用中,路由传参是实现页面间数据传递的核心功能。Vue Router 4 提供了多种传参方式,适用于不同的场景。

params 传参(路径参数)

带参数的动态路由匹配,在 Vue Router 中,可以在路径中使用一个动态字段来实现,称之为 路径参数

路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 route.params 的形式暴露出来。

使用示例:

  • 路由配置

    // 路由配置
    const routes = [
      {
        path: '/user/:id',  // 动态字段以冒号开始
        name: 'user',  		// 使用params时,必须搭配name使用。如果提供的path,则params会被忽略
        ***ponent: User
      }
    ]
    
    • 同一个路由中可以设置多个路径参数,多个参数之间通过斜杠 / 分隔,它们会映射到 $route.params 上的相应字段

      匹配模式 匹配路径 route.params
      /user/:id /user/123 { id: '123' }
      /user/:id/:username /user/123/zhangsan { id: '123', username: 'zhangsan' }

      可选参数:通过在参数后添加 ? 标记,使其成为可选参数。

    • { path: '/user/:age?', ***ponent: User }
      
  • 传递参数

    <template>
        <!-- 通过路由链接 -->
        <router-link :to="{ name: 'user', params: { id: 123 }}">用户</router-link>
    </template>
    
    <script>
        // 选项式API
        export default {
            methods: {
                goUserDetail() {
                    // 通过编程式导航
                    this.$router.push({ name: 'UserDetail', params: { id: 123 } });
                },
            },
        };
    </script>
    
    <script setup>
        // 组合式API
        import { useRoute } from 'vue-router';
        const route = useRoute();
        function goUserDetail() {
            // 通过编程式导航
            route.push({ name: 'UserDetail', params: { id: 123 } });
        }
    </script>
    
  • 获取参数

    <script setup>
        import { useRoute } from 'vue-router';
        const route = useRoute();
        console.log(route.params.id); // 输出: 123
        
        // 可选参数获取
        const userAge = route.params.age || 'defaultId';  // 提供默认值
    	console.log(userAge);   // 输出: "12" 或 "defaultId"
    </script>
    

query 传参(查询参数)

查询参数通过 URL 的查询字符串传递,适合传递可选参数、过滤条件等。

查询参数不会影响路由匹配,适合频繁变化的参数。

  • 传递参数

    <template>
    	<!-- 通过路由链接 -->
        <router-link :to="{ name: 'UserList', query: { page: 2, size: 10 } }">第二页</router-link>
    </template>
    
    <script setup>
        // 组合式API
        import { useRoute } from 'vue-router';
        const route = useRoute();
        function goUserDetail() {
            // 通过编程式导航
            route.push({ name: 'UserList', query: { page: 2, size: 10 } });
        }
    </script>
    

    获取参数

    <script setup>
        import { useRoute } from 'vue-router';
        const route = useRoute();
        console.log(route.query.page);  // 2
        console.log(route.query.size);  // 10
    </script>
    

props 传参

使用 props 选项将路由参数解耦为组件的普通 props,提高组件的复用性。

  • 路由配置

    方式1:布尔模式

    const routes = [
        {
            path: '/user/:id',
            name: 'user',
            ***ponent: User,
            props: true	// 当props设置为true时,route.params将被设置为组件的props
        },
        
        // 有命名视图的路由,必须为每个命名视图定义 props 配置
        {
            path: '/user/:id',
            ***ponents: { default: User, sidebar: Sidebar },
            props: { default: true, sidebar: false }
        },
    ]
    

    方式2:函数模式

    可以创建一个返回 props 的函数。这允许将参数转换为其他类型,将静态值与基于路由的值相结合等

    const routes = [
        {
            path: '/user/:id/:age',
            name: 'user2',
            ***ponent: User,
            props: (route) => ({ id: route.params.id, age: route.params.age }) // params传参
        },
        {
            path: '/about',
            name: 'about',
            ***ponent: About,
            props: (route) => ({ age: route.query.age }) // query传参
        },
    ]
    

    方式3:对象模式

    props 是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。

    const routes = [
        {
            path: '/profile',
            name: 'profile',
            ***ponent: Profile,
            props: { isStudent: false } // 对象形式
        }
    ]
    
  • 获取参数

    <script>
        // 选项式API
        export default {
          props: ['id', 'age', 'isStudent'],
          setup(props) {
            console.log(props.id)
          }
        }
    </script>
    
    <script setup>
        // 组合式API
        const props = defineProps<{
            id: number;
            age: number;
            isStudent: boolean;
        }>();
    </script>
    
转载请说明出处内容投诉
CSS教程网 » vue-router(vue 路由)基本使用指南(一)

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买