动态路由
动态路由
配置静态路由
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个
User
组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在vue-router
的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
在配置路由时,在需要动态生成的前面加上:
router.js
{
path: '/user/:userId',
component: user
}
HTML
这里userId可以直接使用静态数据,如
用户
也可以使用data方法或者computed方法里的动态数据,这时要使用v-bind进行绑定
用户
获取当前路由数据
当前路由数据可以通过$route
来获取,该属性包含了当前选中路由的信息
可调用该属性的params
来获取数据,该属性的数据类型是对象类型,包含了当前动态路由的键值对
JS
data() {
return {
userId: this.$route.params.userId
}
}
路由懒加载
如果按照以前的方式配置路由,在页面加载时会一次性加载所有的js文件,会使得网页加载变慢
这个时候build工程文件,会生成以下三个文件
- app.js ==> 保存的是我们自己编写的代码
- manifest.js ==> 保存的是一些底部支撑代码
- vendor.js ==> 保存的是外部文件代码,如Vue
如果使用路由懒加载,在加载文件的时候只会在调用那个路由时才会加载对应的JS文件
官方文档
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合 Vue 的异步组件 (opens new window)和 Webpack 的代码分割功能 (opens new window),轻松实现路由组件的懒加载。
首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):
const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
第二,在 Webpack 2 中,我们可以使用动态 import (opens new window)语法来定义代码分块点 (split point):
import('./Foo.vue') // 返回 Promise
结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
const Foo = () => import('./Foo.vue')
现在来将我们以前的代码设置成懒加载模式
只需要做很简单的改变,通俗来讲就是,将以前的
import home from "../components/home";
import show from "../components/show";
import user from "../components/user";
改成
const home = () => import('../components/home')
const show = () => import('../components/show')
const user = () => import('../components/user')
这样一来,当我们build工程文件时,除了生成以上3个文件外,还会额外生成0,1,2这3个JS文件
这三个JS文件对应的便是这三个路由调用时对应的JS文件
嵌套路由
嵌套路由,就是在路由页面再进行路由的分配
例如,我们想在home页面再进行message和news的路由分配
首先肯定是要定义好这两个组件
然后在router.js里面设置路由,使用children关键字
children
里面设置路由信息,也是设置path
和component
{
path: '/home',
component: home,
children: [
{
path: '/home/message',
component: home_message
},
{
path: '/home/news',
component: home_news
}
]
},
接着在组件内定义router-link
和router-view
例如,这里我们是在home里面定义的
在home里设置router-link
和router-view
信息
新闻
通过query传递数据
之前设置动态路由时是通过router里的对象进行传递的,其实还有一种传递数据的方式是query(查询),这种传递数据的方式有点类似于get提交数据
和之前配置路由相同,首先定义组件,然后在router.js设置路由组件
不同的是在组件使用时,to的值是以对象的形式传递的
例如
用户信息
{{$route.query.name}}
{{$route.query.sex}}
{{$route.query.hobby}}
我们使用path与query属性
在取数据时使用query属性便可取到相应的值
导航守卫
全局前置守卫
正如其名,
vue-router
提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察
$route
对象来应对这些变化,或使用beforeRouteUpdate
的组件内守卫。
在路由跳转时,如果我们需要添加一些事件,便可以调用该方法
比如,我们想在跳转时,将页面的title进行更改
首先需要在route对象里面添加属性,我们将route属性的meta属性重写
例如
{
path: '/show',
component: show,
meta: {
title: '展示'
}
},
这样每一个route对象便有一个对应的值了
接着使用 router.beforeEach
注册一个全局前置守卫:
例如
router.beforeEach((to, from, next) => {
document.title = to.matched[0].meta.title
console.log(to)
next()
})
其中to和from的参数是router类型,分别表示从哪个路由来要到哪个路由去
next是方法,可以进行重定向,记住全局前置守卫里面一定要有这个方法,不然跳转不生效
matched是数组,大致可以理解为是路由嵌套,我们始终选择第一个
全局后置守卫
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受
next
函数也不会改变导航本身:
router.afterEach((to, from) => {
// ...
})
路由独享的守卫
你可以在路由配置上直接定义
beforeEnter
守卫:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
这些守卫与全局前置守卫的方法参数是一样的。
除此之外,还有全局解析守卫,组件内的守卫等等
keep-alive
在路由页面配置时,实现页面跳转实际上是不断创建组件与销毁组件的过程,若不希望组件被销毁,就可以使用keep-alive
使用方法:
将需要保留的组件放置在keep-alive
标签中
例如:
在使用keep-alive时还提供了两个方法:
- activated
- deactivated
这两个方法在组件处于活跃状态或者不活跃状态时使用
该方法须在keep-alive
包含的组件中调用
keep-alive
还包含两个关键字:
- include
- exclude
分别表示包含的组件和不包含的组件
如果我们不希望某个组件保留,就可以使用关键字exclude
例如
其中exclude的参数是组件名称
切记,exclude的参数不可以含有空格