路由(Vue Router)用于管理不同页面或视图的跳转和展示。它通过控制应用的 URL 路径与组件之间的映射关系,实现在单页应用(SPA)中的页面切换,提供了良好的用户体验,而无需重新加载整个页面。
npm install vue-router@4
指定安装路由版本4,适配于vue3
路由的 history 和 hash 模式是两种不同的 URL 路由管理方式,它们都通过 Vue Router 来实现前端路由的控制。
Hash 模式 是通过 URL 中的 hash(即 #
后的部分)来实现路由的。浏览器会将 hash 后面的路径视为当前路由状态,改变 hash 不会导致页面重新加载。
在这种模式下,URL 中的 hash 部分不包含在 HTTP 请求中,浏览器不会向服务器发送包含 #
的 URL。只有浏览器端的 JavaScript 会解析和更新 hash 值来控制页面的内容。
优点:
const routers = createRouter({
mode:'hash'
})
与 hash 模式不同,URL 中没有 #,这使得路由看起来更加干净、自然,并且符合常规的 URL 格式。但对应的要求服务器能够正确处理页面刷新时的路径。如果用户在浏览器地址栏中输入一个特定的路径,服务器必须返回应用的 index.html
页面,而不是直接返回 404 错误。这就需要对服务器做一些配置(例如 Nginx、Apache、Node.js 等服务器需要进行额外配置)。
例如,http://example.com/home
看起来更自然,符合标准的网页地址
const router = createRouter({
mode:'history'
})
路由配置一般包含两个部分:路由的路径以及所对应的组件,可以类比于字典,包含key值与value值
import {createRouter,createWebHistory} from 'vue-router'
import Home from '../page/Home.vue'
import Navagation from '../page/Navagation.vue'
const routes = [
{
path:'/',
name:'Home',
component:Home //传入我们所需要的组件
},
{
path:'/Navagation',
name:'Navagation',
component:Navagation
}] //使用数组去存储对应的路由信息,使用对象的方式进行存储
首先通过数组的方式将路由信息中的属性配置完毕,包含路径,名字,以及所对应的组件。根目录通常使用'/'进行标识,各个父类目录需要使用标识符'/',所对应的子目录直接使用名字即可。
想要在路由中创建子路由在children属性中配置即可,使用数组表示多个子路由
理论上可以进行无限嵌套。
import {createRouter} from 'vue-router'
import Home from '../page/Home.vue'
import User from '../page/user.vue'
import Userinfo from '../page/Userinfo.vue'
import UserSettings from '../page/UserSettings.vue'
const routes = [
{
path:'/',
name:'Home',
component:Home
},
{
path:'/User'
name:'User',
component:User,
children:[{
path:'', //空路径表示为默认子路由
name: 'Userinfo',
component: Userinfo
},
{
path:'UserSeetings', //子路由不需要加标识符'/'
component:UserSettings
}]
}]
请注意,在使用子路由时,只能在父路由页面中渲染,即父路由渲染之后,子路由才在其中渲染,父路由中需要定义
const router = createRouter({
history:createWebHistory(),
routes})
export default router
传入我们的配置信息,包括routes路径对象等。使用默认导出模式方便在Vue应用中添加
//Main.js中与vue实例进行挂载
import {createApp} from 'vue'
import router from './router/index.js' //传入我们的router
import App from './App.vue'
createApp(App).use(router).mount('#app')
//通过use使用路由,挂载在vue实例对象上
创建好路由之后我们会有两个实例对象
用于访问当前路由的状态信息(如路径、参数、查询等),你不能通过 $route
来修改路由。
用于进行路由的编程式导航,控制路由跳转、替换等。
根据名字进行简单区分,$route就是路由,我们需要跳转的界面;$router就是路由器,我们需要路由器进行跳转。一个是目标页面,一个是用来运载的机器。
在模板中配置我们的路由主要是用到两个标签
这是一个组件,用来创建可以进行点击的链接,实现路由跳转,通过to属性配置在路由对象中所配置的path跳转到对应的vue组件上
是一个占位符,用来显示所匹配的组件,会根据当前的路由路径显示对应的组件
//App.vue
URL 的查询字符串(Query String)是 URL 中 ?
后面跟着的部分,它通常用于传递额外的参数和数据。在网页开发中,查询字符串常用于传递表单数据、过滤器、分页信息等。它通过键值对的形式传递信息,每个键值对之间由 &
分隔。
?:表示查询字符的开始
key1=value1:表示第一个查询参数
&:分割多个查询参数
https://example.com/page?key1=value1&key2=value2&key3=value3
传统静态绑定路由使用标识符'to'即可,但当你需要 动态计算 或 动态生成 路由目标时,应该使用 :to
。
在使用to传入需要跳转的组件中可以进行配置参数
参数会保存在所定义的路由实例中的query属性,以下代码调用存储在query中的参数
this.$route.query.name
如果你需要在路由跳转时传递查询参数,且查询参数的值是动态的,使用 :to
可以很方便地绑定查询参数。例如,当你根据某个数据动态生成 URL。
在另一个组件中想要获取上一个组件所传来的参数,可以配置相应的query参数,会存储在路由实例中的$route中
Go to user profile
在子组件中调用
{{this.$route.id}}
另一种方式是通过params参数,当路由跳转时,params
会直接嵌入到 URL 中
需要注意的是,使用params必须与name一起使用,不允许使用path路径
配置params很简单,只需要在原有配置路由中path属性使用占位符进行声明即可
routes = [{path:'/home/:id/:title',name:'Home',component:Home}]
const router = createRouter({history:createWebHistory,routes})
使用:id,:title的形式告诉当前路由需要传入这两个参数
- 使用字符写法
- 使用对象写法
参数传递时,需要指定name而不需要path
会暂存在组件router实例中的params中,使用即可
在接收组件中直接使用即可
this.$route.params.id
作用:控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式,分别为push和replace,push是追加历史记录,replace是替换当前记录,路由跳转默认为push方式
开启replace配置以下信息即可,用户在浏览器中按下后退键不会有任何历史路由的返回
编程式路由导航(Programmatic Navigation)是指通过 JavaScript 代码来控制路由的跳转,而不是通过点击
或用户行为触发的路由变化。
通过路由内置的不同API来进行操作
$router.push()
方法将当前路径添加到历史记录栈中,跳转到目标路径
this.$router.push('/home'); // 跳转到 /home 路径
也可以配置其他参数
this.$router.push({ name: 'detail', params: { id: 123 } });
$router.go()
用于模拟浏览器的前进或者后退操作,可以接受一个整数作为参数,表示跳转的历史纪录步数
router.go(1)
:前进一步router.go(-1)
:后退一步this.$router.go(-1)
让不展示的组件即便被切换仍然保持挂载,不被销毁
Vue2中的用法:
include指定缓存的组件名,注意,该名是在router配置中的name属性,组件展示的标签被keep-alive包裹,指定缓存内容。
缓存多个组件
定义在不同路由组件内部,即vue文件中
路由组件被激活时触发
activated(){
console.log('被触发')
}
路由组件失活时触发
deactivated(){
console.log('组件已失活')
}
在 Vue.js 中,路由守卫 是一种机制,用于在路由跳转的过程中进行一些自定义操作。路由守卫可以在路由切换的不同阶段被触发,允许你控制路由的跳转流程。这为我们提供了一个灵活的方式来管理应用中的路由行为,执行权限验证、数据加载、导航重定向等操作
存储路由相关的元数据(metadata)。这些元数据可以包含任何你需要的信息,例如:页面标题、权限信息、访问控制、SEO 相关的元数据等。在 Vue Router 的路由配置中,你可以为每个路由定义一个 meta
属性,通常是一个对象,包含一些你自定义的字段。例如,页面的标题、是否需要认证等。
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import Login from './views/Login.vue'
import Admin from './views/Admin.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: 'Home Page' } // 自定义的 meta 数据
},
{
path: '/login',
name: 'Login',
component: Login,
meta: { title: 'Login Page' }
},
{
path: '/admin',
name: 'Admin',
component: Admin,
meta: { title: 'Admin Dashboard', requiresAuth: true } // 需要认证才能访问
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router;
初始化进行执行,每次路由转换前执行
const router = createRouter({})
router.beforeEach((to,from,each)=>{})
通过beforeEach函数进行,需要向其中传入一个回调函数,回调函数包含参数to,from,each。分别代表去到哪个组件,从哪个组件来,以及each是放行的方法
举个例子,我们想要验证localStorage中是否存在相应的信息以此模拟用户信息来显示是否需要展示对应内容:
router.beforeEach((to, from, next) => {
console.log('前置路由守卫')
//if (to.path === '/Navagation') { //常规方式进行守卫鉴别
if (to.meta.active) { //通过meta中的布尔值判断是否需要鉴别
if (localStorage.getItem('school') === 'MIT') { next() }
else {next('/')} //返回主页面
}
else {each() }
})
如果验证成功,则调用each()可以放行,如果不添加此方法,则用户将会一直停留在此组件。
每次路由切换之后进行执行,常用于标签页面title的切换
router.afterEach((to,from,each)=>{
document.title = ''
each()
})
对于想要验证才可进入的组件内部中配置相关的参数,
与全局守卫方法类似,但不含有后置守卫。配置在router总文件中相关路由信息中,当当前组件被调用之前自动执行回调函数中的内容:
const router = createRouter({
{
path:'/news',
beforeEnter((to,from,next)=>{console.log('OK')})
}
})
其中to这个传入参数传入的实际上就是当前组件
该方法定义在组件内部实例中,即vue文件中,更加专一化对组件实现路由守卫。
即在vue实例中配置之后,每当进入该组件或者离开该组件自动调用钩子内容
进入守卫,通过路由规则(即一般网页输入对应标签无法调用此方法,需要按照我们自定义的进路由规则才可调用该方法),进入该组件时进行调用
//xxx.vue
离开守卫,通过路由规则,离开该组件时进行调用
相关案例:
export default {
name: 'AdminPage',
beforeRouteEnter(to, from, next) {
const isAuthenticated = checkUserAuthentication(); // 这里是一个模拟的检查函数
if (isAuthenticated) {
next();
} else {
next('/login'); // 如果用户未认证,重定向到登录页
}
}
}