Vue全家桶包括Vue核心语法(Vue Core)、Vue-Router、Vuex(Pinia),这篇文章笔者就从浅入深的聊聊Vue-Router,废话没有,全是干货。
简单搭建一个Vue路由的流程
安装
Vue-Router
npm install -S vue-router
在项目的新建
src/router/index.js
文件// 导入两个必要的函数 import { createRouter, createWebHashHistory } from 'vue-router' // 导入对应的组件 import Home from '../views/Home.vue' // 创建对应关系 const routes = [ { path: '/', redirect: '/home' }, // redirect 是路由重定向 { path: '/home', component: Home } ] const router = createRouter({ routes, // routes: routes 的高级写法 // createWebHashHistory 是hash模式,在服务端不需要配置,比较方便。 // 还有一种H5新增的history模式,区别不多赘述,也不再演示。 history: createWebHashHistory() }) // 导出路由配置文件 export default router
在项目
main.js
中使用路由// 省略其他的代码 // 导入路由配置文件 import router from './src/router' import { createApp } from 'vue' const app = createApp() // 挂载路由配置 app.use(router) app.mount('#app')
在项目
App.vue
中使用路由路由占位符
<router-view></router-view>
<template> <!-- 占位符 渲染的路由组件的位置 !--> <router-view></router-view> </template>
路由跳转使用
<router-link></router-link>
<template> <!-- to属性代表要跳转的路径 !--> <router-link to="/home">首页</router-link> <router-link to="my">我的</router-link> </template>
路由基本使用的补充
路由重定向
通常情况下用户一开始访问的是
/
根路径是没有组件展示的,可以使用redirect
属性设置路由重定向到另一个路由地址routes: [ // 路由重定向到 /home路由 { path: '/', redirect: '/home' }, { path: '/home', component: Home } ]
路由模式
Vue-Router
路由模式有hash
模式和history
模式hash
模式的使用上文所介绍,下面介绍history
模式的基本使用// 在 src/router/index.js 文件中 // 省略其他代码 // 引入 createWebHistory history模式 import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ routes: [{},{}], history: createWebHistory() }) export default router
router-link
的选项to
属性跳转的路径都有记录,可以通过浏览器的后退键退回上一个页面。还可以传递对象
:to={ path: '/home' }
。replace
属性跳转路径之后不会形成一个记录 ,不能通过浏览器的后退键退回上一个页面。active-class
属性可以自定义选择的选项都是类名,active-class="active"
表示自定义点击的类名为active
。exact-active-class
属性用于嵌套路由中的精确匹配的一个类名。
路由懒加载
路由懒加载可以使得页面加载速度更快,使用import
函数,其是一个Promise
,核心原理是分包加载。
/* webpackChunkName: 'home' */
这是一个魔法注释,用于webpack
打包过程中对于分包名称的修改。
// import函数导入组件
// /* webpackChunkName: 'home' */ 在webpack打包时重命名
const Home = () => import(/* webpackChunkName: 'home' */'../views/Home.vue')
const routes = [
{
path: '/home',
component: Home
},
// 另外一种写法 不用单独导入用变量接收
// 依旧可以使用魔法注释
{
path: '/about',
component: () => import('../views/About.vue')
}
]
路由的其他属性
name
属性路由记录独一无二的值。
meta
属性自定义的数据
{
name: 'home, // 独一无二的名称
path: '/home'
component: () => import(),
meta: {
title: '首页' // meta是自定义的数据
}
}
动态路由
有些路由需要匹配一个相同的组件,如果路由有很多,一个一个写不现实,就可以使用动态参数自动匹配,这就是动态路由
{
path: '/user/:id', // :id 就是用来动态匹配的一个参数
component: Home
}
获取动态路由的参数
- 在
template
模板中可以使用$route.params.id
获取相应的参数。 在
script
节点中获取参数- 在
options API
中使用this.$route.params.id
获取相应的参数 在
composition API
中方法具体如下:import { useRoute } from 'vue-router' const route = useRoute() const id = route.params.id
- 在
设置 404 Not Found
页面路由
当路径错误时提示用户,使用pathMatch()
可以实现此功能。
// 404 路由放在路由表最后一项
[
{},
...,
// 404 路由
{
path: '/:pathMatch(.*)',
component: () => import('404页面的加载') // 路由懒加载
},
]
如果path: '/:pathMatch(.*)*'
,则会将路径以/
分割为一个数组,不加*
则不会分割为数组。
url: 123/223/aaa
解析为
["123", "223", "aaa"]
路由嵌套
使用children
属性进行路由嵌套。
[
{
path: '/home',
component: ,
children: [
// 依旧可以使用 redirect 属性来重定向路由
{ path: '/home', redirect: '/home/product' },
{
path: 'product', // 相当于 /home/product
component: , // 依旧可以使用路由懒加载
// 还可以嵌套
children: [
{},
{}
]
},
]
}
]
在Home.vue
组件中添加路由占位符切换对应的组件
<template>
<div>
Home.vue
</div>
<router-view></router-view>
</template>
编程式导航
在使用其他标签时,无法使用to
属性进行路由的跳转,可用的方法有push
,replace
等等。在composition API
中使用编程式导航的方法如下:
import { useRouter } from 'vue-router'
const router = useRouter()
// 使用 push跳转 有记录 可退回
router.push('/about')
// 或者 以对象的形式进行跳转 可以传参数
router.push({
path: '/about',
query: {
name: hhh,
age: 15
}
})
// 使用 replace 跳转 替换记录 不可退回
router.replace('/home')
// 前进 or 后退
router.forward // 前进
router.back() // 后退
router.go(-1) // 向后退一层
router.go(1) // 向前进一层
push
和repalce
的区别:
push
进行跳转会有记录,可以后退replace
进行跳转会覆盖掉之前的记录,不可后退
动态添加路由
对于不同角色适当的添加一些新的路由。使用addRoute()
函数可以实现此操作,具体操作如下:
添加一级路由
const router = createRouter({ routes: [], ... }) let isAdmin = true // 如果 isAdmin 为真,则新增一条路由 if (isAdmin) { router.addRouter({ path: '/admin', component: () => import() }) }
添加子路由
addRoute('父路由的name', {...})
用于新增子路由const router = createRouter({ routes: [ {name: 'home', path: '/home'} ], ... }) let isAdmin = true // 如果 isAdmin 为真,则新增一条子路由 if (isAdmin) { router.addRoute('home', { path: 'vip', component: () => import() }) } // 另外一种写法 const vipRoute = { path: 'vip', component: () => import() } if (isAddmin) { router.addRoute('home', vipRoute) }
删除路由
添加一个相同
name
的路由router.addRouter({ path: '/home', name: 'home', component: Home }) // 会覆盖之前的路由,因为它们的 name 必须唯一 router.addRouter({ path: '/other', name: 'home', component: Other })
通过
removeRoute()
方法,传入路由的名称router.addRouter({ path: '/home', name: 'home', component: Home }) // 删除路由 router.removeRoute('home')
通过
addRoute()
方法的返回值调用删除路由const removeRoute = router.addRoute({}) // 删除路由 如果存在的化 removeRoute()
路由其他方法补充
router.hasRoute()
:检查路由是否存在router.getRoutes()
:获取一个包含所有路由记录的数组。
路由导航守卫
全局前置守卫
beforEach(() => {})
它有三个参数:
to
:即将进入的路由Route对象from
:即将离开的路由Route对象next
:符合守卫的放行条件,放行next()
,Vue3
不推荐使用
它的返回值:
- false:取消当前导航
- 不返回或者undefined:进行默认导航
返回一个路由地址:
- 可以是一个
string
类型的路径 - 可以是一个对象,对象中包含
path、query、params
等信息
- 可以是一个
具体演示:
场景:进入路径 my 对应的组件必须登录(token值不为空)。
const router = createRouter({})
// 全局前置守卫
router.beforeEach((to, from) => {
const token = localStorage.getItem('token')
// 如果没有 token 且 访问的路径为 my 则被强制跳转到 login 路由对应的组件
if (!token && to.path === '/my') {
return '/login'
}
})
Comments | NOTHING