Vue3 学习笔记(十三)——路由Vue Router 4.x
一、简单路由(不引入一整个路由库)
1、示例(动态组件切换的方式)
<script>
import Home from './Home.vue'
import About from './About.vue'
import NotFound from './NotFound.vue'
const routes = {
'/': Home,
'/about': About
}
export default {
data() {
return {
currentPath: window.location.hash
}
},
computed: {
currentView() {
return routes[this.currentPath.slice(1) || '/'] || NotFound
}
},
mounted() {
window.addEventListener('hashchange', () => {
this.currentPath = window.location.hash
})
}
}
</script>
<template>
<a href="#/">Home</a> |
<a href="#/about">About</a> |
<a href="#/non-existent-path">Broken Link</a>
<component :is="currentView" />
</template>
子组件
<!-- Home.vue -->
<template>
<h1>Home</h1>
</template>
<!-- About.vue -->
<template>
<h1>About</h1>
</template>
<!-- NotFound.vue -->
<template>
<h1>404</h1>
</template>
二、Vue Router基础知识(4.x)
1、概念
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:
- 嵌套路由映射
- 动态路由选择
- 模块化、基于组件的路由配置
- 路由参数、查询、通配符
- 展示由 Vue.js 的过渡系统提供的过渡效果
- 细致的导航控制
- 自动激活 CSS 类的链接
- HTML5 history 模式或 hash 模式
- 可定制的滚动行为
- URL 的正确编码
1)Hash 模式(只看,不用运行示例)
hash 模式是用 createWebHashHistory()
创建的。它在内部传递的实际 URL 之前使用了一个哈希字符(#
)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响。如果你担心这个问题,可以使用 HTML5 模式。
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
//...
],
})
2)HTML5 模式(只看,不用运行示例)
用 createWebHistory()
创建 HTML5 模式,推荐使用这个模式。当使用这种历史模式时,URL 会看起来很 "正常",例如 https://example.com/user/id
。漂亮!
不过,问题来了。由于我们的应用是一个单页的客户端应用,如果没有适当的服务器配置,用户在浏览器中直接访问 https://example.com/user/id
,就会得到一个 404 错误。这就尴尬了。不用担心:要解决这个问题,你需要做的就是在你的服务器上添加一个简单的回退路由。如果 URL 不匹配任何静态资源,它应提供与你的应用程序中的 index.html
相同的页面。漂亮依旧!
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
//...
],
})
nginx配置:
location / {
try_files $uri $uri/ /index.html;
}
其他配置见:服务器配置示例(可以学完这章后再进行研究)
2、安装
npm install vue-router@4
3、简单使用(html;对标上面的简单路由)
1)通过router-link
指定 url 链接;
2)通过router-view
显示与 url 对应的组件;
<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>
4、Vue应用中使用路由(必须掌握的知识)
1)示例1:
// 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({
history: VueRouter.createWebHashHistory(), // 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式(推荐HTML5模式)。
routes, // `routes: routes` 的缩写
})
// 4、创建Vue应用并挂载根实例
const app = Vue.createApp({})
app.use(router) // 整个应用支持的路由;以this.$router 的形式访问。
app.mount('#app') // 挂载
// 5、现在,应用已经启动了!
2)示例2(npm init vue@latest
引导式创建的项目中的代码)
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue')
}
]
})
export default router
3)Vue应用中访问路由组件
在上面的Vue应用的任何地方都可以通过this.$route
来访问路由组件,如: this.$router.push('/login') // 跳转到login页
。
5、动态路由
路径参数
用冒号 :
表示;下面为“现在像 /users/johnny
和 /users/jolyne
这样的 URL 都会映射到同一个路由。”的案例:
const User = {
// 通过更新 User 的模板来呈现当前的用户 ID
template: '<div>User {{ $route.params.id }}</div>',
}
// 这些都会传递给 `createRouter`
const routes = [
// 动态字段以冒号开始
{ path: '/users/:id', component: User },
]
1)多参数使用 路径拼接 的形式标识:/users/:username/posts/:postId(效果举例:/users/eduardo/posts/123)
2)路由的匹配语法(介绍路由联合正则表达式、通配符*使用啥的;还有匹配区分大小写sensitive
、匹配带有尾部斜线的路由路径strict
)
6、嵌套路由
1)嵌套前的根路由
<div id="app">
<router-view></router-view>
</div>
js
const User = {
template: '<div>User {{ $route.params.id }}</div>',
}
// 这些都会传递给 `createRouter`
const routes = [{ path: '/user/:id', component: User }]
2)嵌套后的路由
① 一个被渲染的组件也可以包含自己嵌套的 <router-view>
。例如,我们可以在 User
组件的模板内添加一个 <router-view>
;
② 在路由中配置 children
路由;
<div id="app">
<router-view></router-view>
</div>
...
const User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`,
}
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// 当 /user/:id/profile 匹配成功
// UserProfile 将被渲染到 User 的 <router-view> 内部
path: 'profile',
component: UserProfile,
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 将被渲染到 User 的 <router-view> 内部
path: 'posts',
component: UserPosts,
},
],
},
]
③ 更多见:嵌套的命名路由
7、页面导航
1)页面加载this.$router.push()
// 字符串路径
router.push('/users/eduardo')
router.push(`/user/${username}`) // -> /user/eduardo
// 带有路径的对象
router.push({ path: '/users/eduardo' })
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
router.push({ name: 'user', params: { username: 'eduardo' } })
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user // 注:如果如果提供了 path,params 会被忽略
// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })
// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })
// 替换路由Url;相当于 router.replace({ path: '/home' })
router.push({ path: '/home', replace: true })
2)前进router.forward()
router.forward() // 前进一步
3)后退router.back()
router.back() // 后退一步
4)历史跳转router.go(n)
// 向前移动一条记录,与 router.forward() 相同
router.go(1)
// 返回一条记录,与 router.back() 相同
router.go(-1)
// 前进 3 条记录
router.go(3)
// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)
8、路由传参props
通过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 }]
1)传参模式 - 布尔模式
当 props
设置为 true
时,route.params
将被设置为组件的 props。
// 对于有命名视图的路由,你必须为每个命名视图定义 props 配置
const routes = [
{
path: '/user/:id', // :id是参数
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false } // 这里是布尔模式的写法
}
]
2)传参模式 - 对象模式
// 当 props 是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。
const routes = [
{
path: '/promotion/from-newsletter',
component: Promotion,
props: { newsletterPopup: false } // 这里是对象模式的写法;newsletterPopup: false是参数
}
]
3)传参模式 - 函数模式
你可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
const routes = [
{
path: '/search',
component: SearchUser,
props: route => ({ query: route.query.q }) // URL /search?q=vue 将传递 {query: 'vue'} 作为 props 传给 SearchUser 组件。
}
]
9、路由重定向redirect
1)基础使用
// 1、从 /home 重定向到 /
const routes = [{ path: '/home', redirect: '/' }]
// 2、重定向的目标也可以是一个命名的路由
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
// 3、甚至是一个方法,动态返回重定向目标
const routes = [
{
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
return { path: '/search', query: { q: to.params.searchText } }
},
},
{
path: '/search',
// ...
},
]
// 4、
2)重定向到相对路径
相对位置Url不以`/`开头
const routes = [
{
// 将总是把/users/123/posts重定向到/users/123/profile。
path: '/users/:id/posts',
redirect: to => {
// 该函数接收目标路由作为参数
// 相对位置不以`/`开头
// 或 { path: 'profile'}
return 'profile'
},
},
]
3)路径使用别名
将 /
起一个别名 /home
,意味着当用户访问 /home
时,URL 仍然是 /home
,但是用户访问的为 /
。示例如下:
const routes = [{ path: '/', component: Homepage, alias: '/home' }]
通过别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。数组示例如下:
const routes = [
{
path: '/users',
component: UsersLayout,
children: [
// 为这 3 个 URL 呈现 UserList
// - /users
// - /users/list
// - /people
{ path: '', component: UserList, alias: ['/people', 'list'] },
],
},
]
动态使用别名示例,如下:
const routes = [
{
path: '/users/:id',
component: UsersByIdLayout,
children: [
// 为这 3 个 URL 呈现 UserDetails
// - /users/24
// - /users/24/profile
// - /24
{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },
],
},
]
二、VueRouter进阶
见:VueRouter进阶
本文来自博客园,作者:꧁执笔小白꧂,转载请注明原文链接:https://www.cnblogs.com/qq2806933146xiaobai/articles/17382177.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下