历史记录模式
Vue Router 支持多种历史管理模式,主要区别在于 URL 的表现形式和页面刷新/直接访问时的处理方式。
如果需要最好的兼容性或没有服务器配置权限,使用
Hash 模式
如果需要干净的 URL 并能配置服务器,使用History 模式(该模式下可通过一定的配置,不请求服务器)
Hash模式
特点:
- 使用
URL hash(#)来模拟完整 URL - URL 示例:
http://example.com/#/user/id - 改变
hash不会触发页面刷新,不会向服务器请求该路径 - 兼容性最好,支持所有浏览器,不需要服务器端特殊配置
hash 模式是用 createWebHashHistory() 创建的
import { createRouter, createWebHashHistory } from 'vue-router'const router = createRouter({history: createWebHashHistory(),routes: [//...],
})
HTML5 History 模式
特点:
- 使用HTML5 History API (
pushState,replaceState) - URL 示例:
http://example.com/user/id - URL 更干净,没有
#,现代浏览器支持良好 - 需要服务器端支持,因为直接访问或刷新页面时会向服务器请求改路径
- 需要服务器配置重定向到 index.html
用 createWebHistory() 创建 HTML5 模式
import { createRouter, createWebHistory } from 'vue-router'const router = createRouter({history: createWebHistory(),routes: [//...],
})
一个单页的客户端应用,如果没有适当的服务器配置,用户在浏览器中直接访问 http://example.com/user/id,就会得到一个404错误。
要想解决,需要在服务器上添加一个简单的回退路由。如果URL不匹配任何静态资源,那么会提供应用程序中的 index.html 相同的页面。
路由元信息
在路由配置中附加的额外数据,用于存储与路由相关的自定义信息。这些信息通常用于控制路由行为、权限验证、页面标题设置等。
在大多数前端路由库(Vue Router、React Router)中,路由元信息是通过 meta 字段定义的
const routes = [{path: '/dashboard',component: Dashboard,meta: {requiresAuth: true,title: '控制面板',roles: ['admin', 'editor']}}
]
常见用途
- 权限控制 - 标记路由是否需要认证或特定角色
meta: {requiresAuth: true,roles: ['admin']
}
- 页面标题 - 设置页面标题
meta: {title: '用户设置'
}
- 过渡效果 - 指定页面过渡动画
meta: {transition: 'fade'
}
- 缓存控制 - 决定组件是否应被缓存
meta: {keepAlive: true
}
- 面包屑导航 - 存储用于面包屑的信息
meta: {breadcrumb: '用户详情'
}
在Vue中的使用
// 路由配置
const routes = [{path: '/profile',component: Profile,meta: {requiresAuth: true,title: '个人资料'}}
]// 导航守卫中使用
router.beforeEach((to, from, next) => {if (to.meta.requiresAuth && !isAuthenticated()) {next('/login')} else {next()}
})// 组件内访问
export default {created() {console.log(this.$route.meta.title)}
}
在React中的使用
React Router 没有内置的 meta 字段,但可以通过自定义方式实现
const routes = [{path: '/about',element: <About />,meta: {title: '关于我们'}}
]// 渲染时设置标题
routes.forEach(route => {if (route.meta?.title) {document.title = route.meta.title}
})
访问 meta 字段
routes 配置中的每个路由对象为路由记录。路由记录是可以嵌套的,当一个路由匹配成功后,可能匹配多个路由记录。
一个路由匹配到的所有路由记录会暴露为 route 对象(还有在导航守卫中的路由对象)的 route.matched 数组。我们需要遍历这个数组来检查路由记录中的 meta 字段,但是 Vue Router 还提供了一个 route.meta 方法,是一个非递归合并所有 meta 字段(从父字段到子字段)的方法。
router.beforeEach((to, from) => {// 而不是去检查每条路由记录// to.matched.some(record => record.meta.requiresAuth)if (to.meta.requiresAuth && !auth.isLoggedIn()) {// 此路由需要授权,请检查是否已登录// 如果没有,则重定向到登录页面return {path: '/login',// 保存我们所在的位置,以便以后再来query: { redirect: to.fullPath },}}
})
