vue-router 是基于路由和组件的。
vue-router 的使用
vue-router 的基本使用
- 创建组件;
- 配置组件与路径的映射关系(定义路由);
- 创建路由实例对象,将映射关系挂载到路由实例上,并且配置路由模式;
- 导出路由实例,在
main.js中导入并使用; - 使用路由:
-
- 通过内置组件
router-link来进行导航
- 通过内置组件
-
- 通过内置组件
router-view来渲染组件
- 通过内置组件
JavaScript
创建 /router/index.js
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
// 1. 导入组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'
// 2. 配置组件与路径的映射关系
const routes = [
{
path: '/',
redirect: '/home' // 配置默认路径
},
{ // 路由对象
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
// 3. 创建一个路由实例对象
const router = createRouter({
routes, // 将映射关系挂载到路由对象上
history: createWebHashHistory() // 配置路由模式
// history: createWebHistory()
})
// 4. 导出路由实例
export default router
在 main.js 中:
// 导入路由实例
import router from '../src/router'
const app = createApp(App)
// 挂载到根组件上
app.use(router)
HTML
在任一个组件中,使用 router-link 组件来进行导航,使用 router-view 来渲染组件。
<router-link> 将呈现一个带有正确 href 属性的 <a> 标签。
<!--通过 `to` 属性来指定路径 -->
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view />
注:router-view 跟 router-link 可以不在同一个组件中。
路由懒加载
只有当路由被访问时才加载对应的组件,这样可以提高首屏的渲染效率。我们可以通过动态导入组件的方式来实现。
const routes = [
{
path: '/',
redirect: '/home'
},
{
path: '/home',
component: () => import('../views/Home.vue'),
},
{
path: '/about',
component: () => import('../views/About.vue'),
}
]
动态导入之后,webpack 在打包时就会进行分包操作,对应的组件在打包时就会单独打包,在需要时才会被加载。
分包前:
分包后:
可以通过魔法注释的方式来对打包后的文件进行命名:
component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
动态路由匹配
很多时候我们希望将同一匹配模式下的路由指向同一个组件。例如 '/user/kobe' 跟 '/user/james',它们都是在 '/user' 这个匹配模式下的,我们希望匹配到它们时都渲染 User 组件,这时就可以使用动态路由匹配。
实现方法是,在定义路由时我们不要把路径写死,而是在路径中使用动态的字段:
{
// 通过 :字段名 的方式来定义动态的字段
path: '/user/:username',
component: () => import('../views/User.vue')
}
在进行跳转时,我们需要传递一个确切的路径:
<router-link to="/user/kobe">用户</router-link>
<!-- 或者是 -->
<router-link to="/user/james">用户</router-link>
在组件中,我们可以获取到对应的路由对象,也就可以获取到对应的 路径参数:
<!-- 在模板中通过 $route 来获取路由对象 -->
<div>{{ $route.params.username }}</div>
import { useRoute } from 'vue-router'
export default {
setup() {
// 在 setup 函数中通过 useRoute 方法来获取路由对象
const route = useRoute()
console.log(route.params.username)
}
}
404 Not Found 路由
对于那些没有匹配到的路由,我们通常会匹配到固定的某个页面:
{
path: '/:pathMatch(.*)*',
component: () => import('../views/NotFound.vue')
}
在组件中可以通过 $route.params.pathMatch 获取到路径参数。
嵌套路由(嵌套组件)
目前我们匹配的Home、About、User 等都属于底层路由,我们在它们之间可以来回进行切换,但是呢,Home 页面本身,也可能会在多个组件之间来回切换,这个时候我们就需要使用嵌套路由,在 Home 中也使用 router-view 来占位之后需要渲染的组件。
嵌套路由在配置时,是直接在上一级路由中通过 children 属性来设置的。
子路由的路径在设置时不需要在前面加上 /,在跳转时会自动对路径进行拼接。
例如,嵌套路由如下:
{
path: '/home',
component: () => import('../views/Home.vue'),
// 通过 children 属性来配置嵌套路由
children: [
{
path: 'message',
component: () => import('../views/HomeMessage.vue')
},
{
path: 'shop',
component: () => import('../views/HomeShop.vue')
}
]
}
那么,在跳转时,我们跳转的路径就是:
<router-link to="/home/message">消息</router-link>
<router-link to="/home/shop">商品</router-link>
路由传参
动态添加路由
某些情况下我们可能需要动态的来添加路由,这个时候我们可以使用 addRoute 方法。
动态添加一级路由
const addRoutes = [
{
path: '/books',
component: () => import('../views/Books.vue')
}
]
router.addRoute(addRoutes)
动态添加二级路由
// 一级路由
{
path: '/home',
name: 'Home',
component: () => import('../views/Home.vue')
}
const addRoutes = [
{
path: 'books',
component: () => import('../views/Books.vue')
}
]
router.addRoute('Home', addRoutes)
路由导航守卫
有些时候我们需要在路由进行跳转的时候进行一些操作,比方说如果判断用户没有登录,就跳转到登录页面或者是不允许跳转,这个时候就需要用到导航守卫。
前置导航守卫 beforeEach,在路由跳转之前触发。
router.beforeEach((to, from) => {
// to 即将进入的 route 对象
// from 即将离开的 route 对象
/**
返回值:
false: 不进行跳转
undefined 或者没有返回值:直接跳转
字符串:路径,跳转到该路径
对象:类似于 router.push({})
*/
return
})
router 跟 route 的区别?