❝「目标」: 持续输出!每日分享关于web前端常见知识、面试题、性能优化、新技术等方面的内容。
❞
❝「主要面向群体:」前端开发工程师(初、中、高级)、应届、转行、培训等同学
❞
Day3-今日话题
想必大家经常会在面试中或者工作生活中听到「前端路由」相关的问题或者话题,那么今天我将从以下几个方面聊聊前端路由:
1. 前端路由是什么?
前端路由是指在单页应用(SPA)中,通过在前端管理和控制页面之间的切换和导航的机制。它允许用户在不离开当前页面的情况下浏览不同的内容,提供了更流畅、响应更快的用户体验。前端路由通过监听 URL 的变化,根据不同的路径渲染不同的视图组件,实现页面的无刷新切换。
2. 前端路由模式有哪些?
「Hash 模式」: 在 URL 中使用 # 后面的哈希部分来表示页面路径,例如
http://example.com/#/home
哈希部分的变化不会导致浏览器向服务器发送请求,适用于没有服务器支持的场景。
「History 模式」: 使用浏览器的 History API 来改变 URL 路径,不再需要使用 #,例如
http://example.com/home
这种模式需要服务器支持,但相较于 Hash 模式,URL 更友好
3. 路由守卫是什么?
路由守卫是一些钩子函数,用于在页面导航发生时执行特定的操作,例如验证用户权限、重定向、取消导航等。它们确保用户在访问页面时具有正确的权限和行为。
在 React 中,你可以使用 React-Router 提供的 Route 组件的 「render」、「component」 或 「children」 属性来实现路由守卫。通过在这些属性中编写逻辑,可以在渲染前进行验证或重定向操作。
<Route path="/profile" render={() => {
if (userIsAuthenticated) {
return <Profile />;
} else {
return <Redirect to="/login" />;
}
}} />
<Route path="/dashboard" children={({ match }) => {
return match ? <Dashboard /> : <Redirect to="/login" />;
}} />
在 Vue 中,你可以使用 Vue Router 提供的全局导航守卫和路由独享守卫来实现路由守卫。
vue全局导航守卫:
-
「beforeEach」: 在每次导航发生之前调用。这个守卫可以用来执行一些全局的权限验证、重定向或其他预处理操作。 -
「beforeResolve」: 在每次导航确认之前调用。和 beforeEach 类似,但在 beforeEach 之前调用。在所有异步路由组件被解析之后触发。 -
「afterEach」: 在每次导航完成之后调用。可以用来执行一些清理操作、发送统计信息等。没有 next() 方法,不会影响导航本身 -
「onError」: 在导航过程中出现错误时调用。可以用来处理导航错误。
router.beforeEach((to, from, next) => {
// 在每次导航之前执行
console.log('Before each navigation');
next();
});
router.beforeResolve((to, from, next) => {
// 在每次导航确认之前执行,和 beforeEach 类似
console.log('Before resolve navigation');
next();
});
router.afterEach((to, from) => {
// 在每次导航完成之后执行
console.log('After each navigation');
});
router.onError((err) => {
// 导航错误时执行
console.error('Navigation error:', err);
});
vue路由独享守卫:
-
「beforeEnter」: 在路由进入前调用,只会对当前路由起作用。可以在此进行验证、重定向等操作。
-
「beforeRouteUpdate」: 在当前路由复用时(例如,同一个组件在不同路由间切换)调用,例如在参数变化时。此时,组件实例会被复用,因此你可以通过访问 this 来获取组件实例。
-
「beforeRouteLeave」: 在路由离开前调用,只会对当前路由起作用。用于确认是否允许离开当前路由,例如执行确认提示操作。
-
「beforeRouteEnter」: 在路由进入前调用,只会对当前路由起作用。但与其他守卫不同,这个守卫不会拥有组件的实例,所以不能通过 this 访问组件。可以通过回调函数 next(vm => {}) 获取组件实例。
const routes = [
{
path: '/home',
component: Home,
beforeEnter: (to, from, next) => {
if (isUserAuthenticated()) {
next(); // 允许导航
} else {
next('/login'); // 重定向到登录页面
}
}
},
{
path: '/user/:id',
component: UserProfile,
beforeRouteUpdate: (to, from, next) => {
// 在用户切换不同用户时,根据新的参数更新数据
if (to.params.id !== from.params.id) {
this.fetchUserData(to.params.id);
}
next();
}
},
{
path: '/edit/:id',
component: EditPost,
beforeRouteLeave: (to, from, next) => {
if (this.isDirty) {
if (confirm('You have unsaved changes. Do you really want to leave?')) {
next();
} else {
next(false); // 取消导航
}
} else {
next();
}
}
},
];
{
path: '/profile/:id',
component: UserProfile,
beforeRouteEnter: (to, from, next) => {
// 获取组件实例,并在数据准备好后调用 next()
fetchData(to.params.id, user => {
next(vm => {
vm.user = user;
});
});
}
},
4. 路由表是什么?
路由表由一个个路由配置对象组成,在一个复杂的应用中,路由表可以更加详细,包括嵌套路由、动态路由参数、路由重定向等。例如:
const routes = [
{ path: '/', component: Home },
{
path: '/products',
component: Products,
children: [
{ path: 'shoes', component: Shoes },
{ path: 'clothes', component: Clothes }
]
},
{ path: '/product/:id', component: ProductDetail },
{ path: '/contact', component: Contact },
{ path: '/404', component: NotFound },
{ path: '/:catchAll(.*)', redirect: '/404' }
];
5. 路由参数和查询参数
当构建前端单页应用时,路由参数和查询参数是两种常见的传递数据的机制。它们允许你在不同页面之间传递信息,但在传递方式、用途和实现上有一些区别。
「路由参数:」
-
「定义方式:」 路由参数是直接嵌入在 URL 路径中,通常使用动态的路径片段进行定义。在路径中使用冒号 :
来指示一个参数。例如:/user/:id
。 -
「用途:」 路由参数适用于标识性的信息,如用户 ID、商品 ID 等。在不同路径下,参数值会不同,但路径结构保持一致。 -
「在 Vue 项目中使用:」 在 Vue 项目中,你可以通过 this.$route.params
来访问路由参数的值。 -
「在 React 项目中使用:」 在 React 项目中,你可以使用 useParams()
钩子来获取路由参数的值。
在 Vue 中的路由参数使用:
<template>
<div>
<router-link :to="'/user/' + userId">User Profile</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
userId: 123
};
}
};
</script>
在 React 中的路由参数使用:
import { useParams } from 'react-router-dom';
function UserProfile() {
const { id } = useParams();
return <div>User Profile: {id}</div>;
}
「查询参数:」
-
「定义方式:」 查询参数是通过 URL 的查询字符串传递的,以 ?
开头,多个参数使用&
分隔。例如:/search?q=keyword&page=1
。 -
「用途:」 查询参数适用于传递附加信息,如搜索关键字、分页页码等。不同页面间可以使用相同的路径,通过不同的查询参数来实现不同的功能。 -
「在 Vue 项目中使用:」 在 Vue 项目中,你可以通过 this.$route.query
来访问查询参数的值。 -
「在 React 项目中使用:」 在 React 项目中,你可以使用 useLocation()
钩子和query-string
库来获取和解析查询参数的值。
在 Vue 中的查询参数使用:
<template>
<div>
<router-link :to="{ path: '/search', query: { q: 'keyword' }}">Search</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
// ...
};
</script>
在 React 中的查询参数使用:
import { useLocation } from 'react-router-dom';
import queryString from 'query-string';
function SearchResults() {
const location = useLocation();
const queryParams = queryString.parse(location.search);
const keyword = queryParams.q;
return <div>Search Results for: {keyword}</div>;
}
总之,路由参数和查询参数都是用于在不同页面之间传递数据的方式。路由参数更适用于标识唯一资源,查询参数则适用于传递附加信息或选项。
下一篇文章将分享「路由预加载、懒加载」,欢迎点赞、关注、转发~
本文由 mdnice 多平台发布