在 Vue 3 中,路由指的是应用程序的导航系统,允许你在不同的视图或页面之间进行切换。通过 vue-router 插件,你可以定义路由规则,将 URL 路径映射到 Vue 组件,实现页面间的跳转和状态管理。使用路由,用户可以在应用中导航不同的视图,同时保持浏览器的历史记录。
一 路由的基本使用
1. 安装 vue-router
npm install vue-router@next
2. 创建路由配置
定义路由配置通常在一个单独的文件中完成,例如 router/index.js 或 router/index.ts。配置包括路径、组件和其他路由属性:
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
3. 在应用中使用路由
在你的 Vue 应用中,通常会在 main.js 或 main.ts 中使用 router 实例:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
const app = createApp(App);
app.use(router);
app.mount('#app');
4. 路由视图
使用 组件在你的模板中展示路由匹配的组件。这个组件充当路由占位符:
<script lang="ts" setup name="App">
import {RouterLink,RouterView} from 'vue-router'
</script>
<template>
<div>
<router-view></router-view>
</div>
<RouterLink to="/home" active-class="active">首页</RouterLink>
</template>
5 命名路由
命名路由允许你为每个路由定义一个唯一的名称,方便在应用中引用和导航。定义命名路由时,你可以在路由配置中为每个路由指定一个 name 属性
- 在路由配置中为每个路由指定 name 属性:
const routes = [
{
path: '/home',
name: 'Home',
component: HomeComponent
},
{
path: '/about',
name: 'About',
component: AboutComponent
}
];
- 使用 组件时,可以通过 :to 属性的对象形式来引用命名路由:
<router-link :to="{ name: 'Home' }">Home</router-link>
<router-link :to="{ name: 'About' }">About</router-link>
- 编程式导航
import { useRouter } from 'vue-router';
export default {
setup() {
const router = useRouter();
function goToHome() {
router.push({ name: 'Home' });
}
return { goToHome };
}
};
- 带参数的命名路由
当路由需要参数时,可以在 :to 对象中添加 params 属性:
<router-link :to="{ name: 'UserProfile', params: { id: 123 } }">User Profile</router-link>
编程式导航时也可以传递参数:
router.push({ name: 'UserProfile', params: { id: 123 } });
6 嵌套路由
嵌套路由允许你在一个路由中定义子路由,从而构建层级结构的页面。这样可以在一个页面内展示多个视图或组件。
- 定义嵌套路由
在路由配置中,将子路由定义在父路由的 children 属性下:
const routes = [
{
path: '/dashboard',
component: DashboardLayout,
children: [
{
path: '',
name: 'DashboardHome',
component: DashboardHome
},
{
path: 'settings',
name: 'DashboardSettings',
component: DashboardSettings
}
]
}
];
7 路由重定向
路由重定向的作用是自动将用户从一个路径引导到另一个路径。它可以用于以下几种情况:
- 默认路径:例如,将根路径 / 重定向到主页 /home。
{
path:'/',
redirect:'/about'
}
- 旧路径更新:将旧的或过时的路径重定向到新的路径,以保持链接的有效性。
- 权限控制:将用户重定向到登录页面,如果他们尝试访问受限区域而未登录。
二 路由的操作
1. 导入 useRouter 和 useRoute
在 Vue 3 中,你需要从 vue-router 导入 useRouter 和 useRoute,这两个函数提供了对路由实例和当前路由信息的访问。
import { useRouter, useRoute } from 'vue-router';
2. 进行路由导航
使用 useRouter 来执行路由导航操作。例如,你可以在组件中定义方法来进行导航:
export default {
setup() {
const router = useRouter();
function goToHome() {
router.push('/');
}
function goToUserProfile(userId) {
router.push({ name: 'user-profile', params: { id: userId } });
}
return { goToHome, goToUserProfile };
}
};
3. 访问当前路由信息
使用 useRoute 来访问当前路由的信息,如路径、查询参数和动态路由参数:
export default {
setup() {
const route = useRoute();
console.log(route.path); // 当前路由的路径
console.log(route.params.id); // 动态路由参数
console.log(route.query.search); // 查询参数
return { route };
}
};
4. 路由守卫
你可以在 setup 函数中使用 onBeforeRouteEnter 和 onBeforeRouteUpdate 进行路由守卫:
import { onBeforeRouteEnter, onBeforeRouteUpdate } from 'vue-router';
export default {
setup() {
onBeforeRouteEnter((to, from, next) => {
// 在路由进入之前执行的逻辑
if (/* 条件 */) {
next();
} else {
next('/login');
}
});
onBeforeRouteUpdate((to, from, next) => {
// 在路由更新之前执行的逻辑
if (/* 条件 */) {
next();
} else {
next('/error');
}
});
}
};
5. 使用路由钩子
你可以在 setup 函数中使用 Vue 的生命周期钩子来处理路由相关的逻辑:
import { onMounted } from 'vue';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
onMounted(() => {
console.log('Current route path:', route.path);
// 处理路由信息
});
return { route };
}
};
6. 监听路由变化
使用 watch API 监听路由变化并响应:
import { watch } from 'vue';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
watch(
() => route.params.id,
(newId, oldId) => {
console.log(`Route parameter ID changed from ${oldId} to ${newId}`);
// 执行需要根据路由变化更新的逻辑
}
);
return { route };
}
};
7. 路由懒加载
通过懒加载组件来提高应用的性能:
const UserProfile = () => import('../components/UserProfile.vue');
const routes = [
{
path: '/user/:id',
name: 'user-profile',
component: UserProfile
}
];
8. 使用路由元信息
路由元信息可以用于存储额外的信息,例如权限检查:
const routes = [
{
path: '/admin',
component: AdminComponent,
meta: { requiresAuth: true }
}
];
// 在路由守卫中检查元信息
import { onBeforeRouteEnter } from 'vue-router';
export default {
setup() {
onBeforeRouteEnter((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login');
} else {
next();
}
});
}
};
三 路由的两种工作模式
1 history
模式
- 工作原理
history
模式利用 HTML5 的 History API (pushState, replaceState, 和 popState 事件) 来管理路由。浏览器的 URL 不包含 # 符号,而是直接显示路由的路径部分。需要对服务器进行配置,以确保所有路由请求都返回应用的入口 HTML 文件。
- 优点
- 更清晰的 URL:没有 # 符号,URL 更加整洁和符合标准。
- 支持更复杂的功能:支持浏览器的前进、后退功能,与传统的浏览器行为一致。
- 缺点
- 需要服务器配置:必须配置服务器以处理路由,避免 404 错误。
- 示例
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
5 URL 示例
- 首页:http://example.com/
- 关于页:http://example.com/about
2 hash
模式
- 工作原理
哈希模式使用 URL 的 # 符号后面的部分来表示路由状态。浏览器不会将 # 后面的部分发送到服务器,所有的路由切换都在客户端完成。
- 优点
- 兼容性:几乎所有浏览器都支持哈希模式,且不需要额外的服务器配置。
- 简单:无需配置服务器即可处理路由。
- 缺点
- URL 显得不美观:URL 中包含 # 符号,这可能会影响用户体验和 SEO。
- 某些功能限制:如部分工具或库可能对哈希 URL 的支持较差。
- 示例
import { createRouter, createWebHashHistory } from 'vue-router';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
export default router;
- URL 示例
首页:http://example.com/#/
关于页:http://example.com/#/about
四 路由传参
1 query参数
- 定义路由
Query 参数不需要在路由定义中做特别设置:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Search from '@/components/Search.vue';
const routes = [
{
path: '/search',
component: Search
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
- 访问 Query 参数
在组件中,使用 useRoute 来访问查询参数:
<template>
<div>
<h1>Search Query: {{ query }}</h1>
</div>
</template>
<script>
import { computed } from 'vue';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
const query = computed(() => route.query.q);
return { query };
}
}
</script>
- 路由跳转
使用 useRouter 进行跳转并传递查询参数:
<template>
<button @click="search('vue')">Search for Vue</button>
</template>
<script>
import { useRouter } from 'vue-router';
export default {
setup() {
const router = useRouter();
function search(query) {
router.push({ path: '/search', query: { q: query } });
}
return { search };
}
}
</script>
2 params参数
- 定义路由
首先,设置带有路径参数的路由:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import User from '@/components/User.vue';
const routes = [
{
path: '/user/:id',
component: User
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
- 访问 Path 参数
在组件中,使用 useRoute 来访问路径参数:
<template>
<div>
<h1>User ID: {{ userId }}</h1>
</div>
</template>
<script>
import { computed } from 'vue';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
const userId = computed(() => route.params.id);
return { userId };
}
}
</script>
- 路由跳转
使用 useRouter 进行跳转并传递路径参数:
<template>
<button @click="goToUser(123)">Go to User 123</button>
</template>
<script>
import { useRouter } from 'vue-router';
export default {
setup() {
const router = useRouter();
function goToUser(id) {
router.push(`/user/${id}`);
}
return { goToUser };
}
}
</script>
- 总结
params
参数 是在路由路径中定义的动态部分(如 /user/:id),在 URL 中直接显示,通常用于标识资源的唯一性。在组件中,通过 useRoute 访问 route.params 来获取这些参数。
query
参数 是附加在 URL 末尾的键值对(如 /search?q=vue),用于传递额外的过滤或搜索条件。在组件中,通过 useRoute 访问 route.query 来获取这些参数。