#vue-router
介绍
Vue Router 是 Vue.js 官方的路由管理器。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
安装
直接下载|SDN/NPM/构建开发版
通过npm安装及在js中的配置:
引入
import Vue from 'vue'
import VueRouter from 'vue-router'
激活
Vue.use(VueRouter)
定义路由组件的基础上-定义路由
const routes = [
{ path: '/resume', component: resume },
{ path: '/position', component: (resolve) => {
require(['.src/pages/position/position'], resolve)
},
}
]
生成路由实例
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
或者
const router = new Router({
routes = [
{ path: '/resume', component: resume },
{ path: '/position', component: (resolve) => {
require(['.src/pages/position/position'], resolve)
},
}
]
})
挂载
new Vue({
router,
}).$mount('#app')
上述是在main.js中编写的,但我们通常会把router额外放到一个独立的js文件,方法如上(挂载除外)最后把这个文件默认输出( export default router),然后在把这个文件import 到main.js当中进行挂载就可以了
在页面中使用路由:
<div id="app">
<p>
<!-- 通过传入 `to` 属性指定链接. -->
<!-- router-link 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/position">Go to position</router-link>
<router-link to="/resume">Go to resume</router-link>
</p>
<!-- 路由出口-路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
路由对象是什么
一个路由对象 (route object) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的路由记录 (route records)。
一个路由对象表示当前激活的路由的状态信息
,每次成功导航后都会产生一个新的对象
路由对象出现在多个地方:
- 在组件内,即
this.$route
- 在
$route
观察者回调内 导航守卫的参数
:scrollBehavior
方法的参数:router.match(location)
的返回值
location的值可以有一下几种类型:
‘home’
{path:‘home’}
{ name: ‘user’, params: { userId: 123 }} // 命名路由,变成/user/123
{ path: ‘register’, query: { plan: ‘private’ }} // 带查询参数,变成 /register?plan=private导航守卫的参数
:
router.beforeEach((to, from, next) => {
// `to` 和 `from` 都是路由对象
})
scrollBehavior
方法的参数:
const router = new VueRouter({
scrollBehavior (to, from, savedPosition) {
// `to` 和 `from` 都是路由对象
}
})
vue路由对象为this.$route时的一些属性:
-
$route.path
类型: string
字符串,对应当前路由的路径,总是解析为绝对路径,如 “/foo/bar”。 -
$route.params
类型: Object
一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。 -
$route.query
类型: Object
一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。 -
$route.hash
类型: string
当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。 -
$route.fullPath
类型: string
完成解析后的 URL,包含查询参数和 hash 的完整路径。 -
$route.matched
类型: Array
一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。
const router = new VueRouter({
routes: [
// 下面的对象就是路由记录
{ path: '/foo', component: Foo,
children: [
// 这也是个路由记录
{ path: 'bar', component: Bar }
]
}
]
})
-
$route.name
当前路由的名称,如果有的话。 -
$route.redirectedFrom
如果存在重定向,即为重定向来源的路由的名字。
对象为this.$route的属性
小结(8):path params query hash fullPath matched name redirectedFrom
vue路由传参query和params的区别
params:/router1/:id ,/router1/123,/router1/789 ,这里的id叫做params
query:/router1?id=123 ,/router1?id=456 ,这里的id叫做query。
1、用法
- query要用path来引入,接收参数都是this.$route.query.name。
- params要用name来引入,接收参数都是this.$route.params.name。
2、效果 - query类似于ajax中get传参,即在浏览器地址栏中显示参数。
- params则类似于post,即在浏览器地址栏中不显示参数。
通过注入路由器,我们可以在任何组件内通过this.$router
访问路由器,也可以通过this.$route
访问当前路由:
this.$router
和this.$route
的区别
- this.$router:
表示全局路由器对象,项目中通过router路由参数注入路由之后,在任何一个页面都可以通过此方法获取到路由器对象,并调用其push(), go()等方法; - this.$route:
表示当前正在用于跳转的路由器对象,可以调用其name、path、query、
params等方法;
命名路由
给路由起名字 配合在$route中属性使用
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
动态路由匹配
如根据不同的id值访问同一个组件
这时就可以在路由路径中使用“动态路径参数”来达到我们要的效果
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,所有的参数值会被设置到this.$route.params
当中,并且参数可以设置多个,可以在每个组件内使用。所以也可以通过this.$route.params.id
来获取参数
模式 匹配路径 $route.params
/user/:username /user/evan { username: 'evan' }
/user/:username/post/:post_id /user/evan/post/123
{ username: 'evan', post_id: 123 }
响应路由参数的变化
当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 对路由变化作出响应...
}
}
}
//组件内的守卫
const User = {
template: '...',
//在当前路由改变,但是该组件被复用时调用
//根据参数的不同访问同一个组件时
beforeRouteUpdate (to, from, next) {
}
}
小结:动态路由匹配以及响应路由参数的变化
router-link
router-link通过to属性指定目标地址,默认渲染成带有正确链接的 a 标签,配置 tag 属性生成别的标签.
<router-link to="/position" tag="div">Go to position</router-link>
router-link VS a 标签
- 让浏览器不再重新加载页面。。。。。
- 当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。有时候我们要让激活 class 应用在外层元素,而不是 a标签本身,那么可以用 router-link 渲染外层元素,包裹着内层的原生 a 标签:
<router-link tag="li" to="/foo">
<a>/foo</a>
</router-link>
######<router-link>
的一些属性:
1、 to
类型: string | Location
表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
2、replace
类型: boolean
默认值: false
设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。
<router-link :to="{ path: '/abc'}" replace></router-link>
3、append
类型: boolean
默认值: false
设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
<router-link :to="{ path: 'relative/path'}" append></router-link>
4、tag
类型: string
默认值: “a”
router-link默认是a标签,如果想把它设置成别的标签那么就使用tag标签
<router-link to="/foo" tag="li">foo</router-link>
5、active-class
类型: string
默认值: “router-link-active”
设置 链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置。
<router-link :to="/home" active-class="u-link--Active">Home</router-link>
6、exact-active-class
类型: string
默认值: “router-link-exact-active”
配置当链接被精确匹配的时候应该激活的 class。注意默认值也是可以通过路由构造函数选项 linkExactActiveClass 进行全局配置的。
7、exact [ɪɡ’zækt]
类型: boolean
默认值: false
每个路由被激活的时候都会设置class类名,但是使用exact这个属性就意味着只有在特定的路由地址才会激活链接类名
<!-- 这个链接只会在地址为 / 的时候被激活 -->
<li><router-link to="/">全局匹配</router-link></li>
<li><router-link to="/" exact>严格匹配</router-link></li>
简单点说,第一个的话,如果地址是/aa,或/aa/bb,……都会匹配成功,
但加上exact,只有当地址是/时被匹配,其他都不会匹配成功
8、event
类型: string | Array<string>
默认值: ‘click’
声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。
<router-link to="/document" event="mouseover">document</router-link>
如果我们不加event,那么默认情况下是当我们点击document的时候,跳转到相应的页面,但当我们加上event的时候,就可以改变触发导航的事件,比如鼠标移入事件
<router-link>
属性小结(8个属性):
to replace append tag active-class exact event exact-active-class
命名视图
一个组件内同时展示多个视图
html
<div>
<div class="container">
<router-view/>
</div>
<div>
<router-view name="orderInguide"></router-view>
</div>
<div>
<router-view name="delivery"></router-view>
</div>
<div>
<router-view name="history"></router-view>
</div>
</div>
js
{
path: '/',
name: 'home',
components: {
//默认输出hemo
default:Home,
//视图名:视图对应组件
"orderInguide":OrderInguide,
"delivery":Delivery,
"history":History
}
},
嵌套命名视图
html
<!-- UserSettings.vue -->
<div>
<h1>User Settings</h1>
<NavBar/>
<router-view/>
<router-view name="helper"/>
</div>
js
{
path: '/settings',
// 你也可以在顶级路由就配置命名视图
component: UserSettings,
children: [{
path: 'emails',
component: UserEmailsSubscriptions
}, {
path: 'profile',
components: {
default: UserProfile,
helper: UserProfilePreview
}
}]
}
嵌套路由
即在 VueRouter 的参数中使用 children 配置
routes: [
{
path: '/',
name: 'about',
component: About,
redirect:'/about/context',
children:[
{
path: '/about/context',
name: 'context',
component: Context,
redirect:'/phone',
children:[
{
path:'/phone',
name:'phone',
component:Phone
},
{
path:'/personName',
name:'personName',
component:PersonName
}
]
}
]
}
]
要注意,以 / 开头的嵌套路径会被当作根路径,children可以多层嵌套
redirect:’/phone’ 默认路由地址
编程式的导航
<router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
注意: $router访问的是路由器
r
o
u
t
e
访
问
的
是
当
前
的
路
由
(
比
如
q
u
e
r
y
−
p
a
r
a
m
s
.
.
.
)
1
、
route访问的是当前的路由(比如query-params...) 1、
route访问的是当前的路由(比如query−params...)1、router.push()
申明式 编程式
<router-link :to="..."> router.push/repalce(...)
to和push的参数类型可以是以下几种类型:
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path,params 会被忽略,
也可以写成这样
const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
2、$router.replace() 跟 router.push 很像区别:
- router.push(); //直接添加一个路由,表现切换路由,本质往历史记录里面添加一个
- router.replace() //替换路由,不会往历史记录里面添加
3、$router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
/ 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
小结:$router.push/replace/go()
重定向和别名
“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,
重定向
重定向的三种方式
const router = new VueRouter({
routes: [
//1
// { path: '/a', redirect: '/b' }
//2
{ path: '/a', redirect: { name: 'foo' }}
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
别名:访问的是b url地址显示的是a
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。
路由组件传参
在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
使用 props 将组件和路由解耦:
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
//props
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true },
// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
props的三种模式
1、布尔模式
如果 props 被设置为 true,route.params 将会被设置为组件属性。
2、对象模式
如果 props 是一个对象,它会被按原样设置为组件属性。
const router = new VueRouter({
routes: [
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
]
})
3、函数模式
你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。
const router = new VueRouter({
routes: [
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})
[vue-router通过url传递参数给组件的props]
(https://blog.csdn.net/huipo22/article/details/80167136)
URL /search?q=vue 会将 {query: ‘vue’} 作为属性传递给 SearchUser 组件。
小结:路由组件传参 props代替动态路由参数 及props的三种类型(布尔、对象、函数)
路由元信息
和 HTML 中 header 部分的 meta 页面原信息类似,例如 description 有助于 seo 等,一般和路由没什么关系的配置可以写在这。
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: {
title: 'this is app',
description: 'xxx',
requiresAuth: true
}
}
]
}
]
})
怎么访问到它呢?
一个路由匹配到的所有路由记录会暴露为 $route 对象 (还有在导航守卫中的路由对象) 的 $route.matched 数组。因此,我们需要遍历 $route.matched 来检查路由记录中的 meta 字段。
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()
}
})
导航守卫
router.beforeEach 全局前置守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
-
to: Route: 即将要进入的目标 路由对象
-
from: Route: 当前导航正要离开的路由
-
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
-
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
-
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
-
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
-
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
导航守卫怎么实现错误回调
因为项目里用了懒加载,每次重新build之后有修改过的文件哈希码会改变,导致路由跳转到有修改过的页面会报页面文件404。所以想要在导航守卫执行next()的时候,如果发生错误就回调回来,重新刷新一次页面,让哈希码更新到最新就能够解决问题。
router.beforeEach((to, from, next) => {
next(error);
})
router.onError(error => {...});
全局解析守卫
router.beforeResolve 全局守卫 这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
全局后置钩子 不会接受 next 函数也不会改变导航本身
router.afterEach((to, from) => {
// ...
})
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
//只适用于beforeRouteEnter
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
路由独享的守卫
beforeEnter
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的守卫
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
完整的导航解析流程
1、导航被触发。
2、在失活的组件里调用离开守卫。
3、调用全局的 beforeEach 守卫。
4、在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
5、在路由配置里调用 beforeEnter。
6、解析异步路由组件。
7、在被激活的组件里调用 beforeRouteEnter。
8、调用全局的 beforeResolve 守卫 (2.5+)。
9、导航被确认。
10、调用全局的 afterEach 钩子。
11、触发 DOM 更新。
12、用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
vue的其他一些的实例化方法:
router.back():回退一步
router.forward():前进一步
router.go(n):指定前进/回退的步数
router.push():导航到不同的 url,向 history 栈添加一个新的记录
router.replace():导航到不同 url,替换 history 栈中当前记录
小结:
有三种方式可以植入路由导航过程中:
全局的
前置守卫:router.beforeEach router.beforeResolve 后置钩子:router.afterEach
单个路由独享的: beforeEnter(写在路由配置中)
组件级的:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
数据获取
有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:
- 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
- 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。
导航完成后获取数据
当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。
假设我们有一个 Post 组件,需要基于 $route.params.id 获取文章数据:
<template>
<div class="post">
<div class="loading" v-if="loading">
Loading...
</div>
<div v-if="error" class="error">
{{ error }}
</div>
<div v-if="post" class="content">
<h2>{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
</div>
</template>
export default {
data () {
return {
loading: false,
post: null,
error: null
}
},
created () {
// 组件创建完后获取数据,
// 此时 data 已经被 observed 了
this.fetchData()
},
watch: {
// 如果路由有变化,会再次执行该方法
'$route': 'fetchData'
},
methods: {
fetchData () {
this.error = this.post = null
this.loading = true
// replace getPost with your data fetching util / API wrapper
getPost(this.$route.params.id, (err, post) => {
this.loading = false
if (err) {
this.error = err.toString()
} else {
this.post = post
}
})
}
}
}
在导航完成前获取数据
通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后只调用 next 方法。
export default {
data () {
return {
post: null,
error: null
}
},
beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) => {
next(vm => vm.setData(err, post))
})
},
// 路由改变前,组件就已经渲染完了
// 逻辑稍稍不同
beforeRouteUpdate (to, from, next) {
this.post = null
getPost(to.params.id, (err, post) => {
this.setData(err, post)
next()
})
},
methods: {
setData (err, post) {
if (err) {
this.error = err.toString()
} else {
this.post = post
}
}
}
}
小结:导航完成之后获取路由数据 (通过组件当中的created()获取)
导航完成之前获取路由数据 (通过路由的生命周期获取 )
路由的滚动行为
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
return { x: 0, y: 0 }
}
})
scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
这个方法返回滚动位置的对象信息,长这样:
{ x: number, y: number }
{ selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)
如果返回一个 falsy (译者注:falsy 不是 false)的值,或者是一个空对象,那么不会发生滚动。
通过Falsy Bouncer(算法)得出Falsy值,当进行逻辑判断时均为false(如!!false==false)。六个Falsy值:false、undefined、null、正负0、NaN、""。
savedPosition
在按下 后退/前进 按钮时,就会像浏览器的原生表现那样:
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
滚动到锚点
scrollBehavior (to, from, savedPosition) {
return {selector:'className'}
}
异步滚动
scrollBehavior (to, from, savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: 0 })
}, 500)
})
}
小结:滚动行为:
1、自定义位置
2、滚动到与元素所对应的位置
3、异步滚动 延迟…
路由懒加载懒加载
懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。
结合 Vue 的异步组件和 Webpack 的代码分割功能
<router-view>
<router-view>
组件是一个 functional(功能) 组件,渲染路径匹配到的视图组件。<router-view>
渲染的组件还可以内嵌自己的 <router-view>
,根据嵌套路径,渲染嵌套组件。
其他属性 (非 router-view 使用的属性) 都直接传给渲染的组件, 很多时候,每个路由的数据都是包含在路由参数中。
因为它也是个组件,所以可以配合 <transition>
和 <keep-alive>
使用。如果两个结合一起用,要确保在内层使用 <keep-alive>
:
<router-view>
name属性
类型: string
默认值: “default”
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
Router 构建选项
1、routes
类型: Array
RouteConfig(路由配置) 的类型定义:
declare type RouteConfig = {
path: string;
component?: Component;
name?: string; // 命名路由
components?: { [name: string]: Component }; // 命名视图组件
redirect?: string | Location | Function;
props?: boolean | Object | Function;
alias?: string | Array<string>;
children?: Array<RouteConfig>; // 嵌套路由
beforeEnter?: (to: Route, from: Route, next: Function) => void;
meta?: any;
// 2.6.0+
caseSensitive?: boolean; // 匹配规则是否大小写敏感?(默认值:false)
pathToRegexpOptions?: Object; // 编译正则的选项
}
2、mode
类型: string
默认值: “hash” (浏览器环境) | “abstract” (Node.js 环境)
可选值: “hash” | “history” | “abstract”
配置路由模式:
- hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。
- history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
- abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。
3、base
类型: string
默认值: “/”
应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 “/app/”。
4、linkActiveClass
类型: string
默认值: “router-link-active”
全局配置 的默认“激活 class 类名”。
5、linkExactActiveClass
类型: string
默认值: “router-link-exact-active”
全局配置 精确激活的默认的 class。可同时翻阅 router-link。
linkActiveClass 和 linkExactActiveClass
6、scrollBehavior
类型: Function
type PositionDescriptor =
{ x: number, y: number } |
{ selector: string } |
?{}
type scrollBehaviorHandler = (
to: Route,
from: Route,
savedPosition?: { x: number, y: number }
) => PositionDescriptor | Promise<PositionDescriptor>
7、parseQuery / stringifyQuery
类型: Function
提供自定义查询字符串的解析/反解析函数。覆盖默认行为。
定制 query 信息
vue 会默认处理,如果有特定需求,可以借助这两个配置项。
/ router.js
export default () => {
return new Router({
parseQuery (query) {},
stringifyQuery (obj) {}
})
}
8、fallback
类型: boolean
不是所有浏览器都支持前端路由的方式,如果不支持,设置 fallback: true,vue 会自动 fallback 到 hash 模式。默认值为 true。
在 IE9 中,设置为 false 会使得每个 router-link 导航都触发整页刷新。它可用于工作在 IE9 下的服务端渲染应用,因为一个 hash 模式的 URL 并不支持服务端渲染。
Vue-router之配置
小结:Router 构建选项(8):routes mode base linkActiveClass linkExactActiveClass scrollBehavior parseQuery / stringifyQuery fallback
Router 实例属性
1、router.app
类型: Vue instance(实例)
配置了 router 的 Vue 根实例。
2、router.mode
类型: string
路由使用的模式。
3、router.currentRoute
类型: Route
当前路由对应的路由信息对象。
小结:Router 实例属性(3)router.app router.mode router.currentRoute
Router 实例方法
router.beforeEach
router.beforeResolve
router.afterEach
router.beforeEach((to, from, next) => {
/* must call `next` */
})
router.beforeResolve((to, from, next) => {
/* must call `next` */
})
router.afterEach((to, from) => {})
router.push
router.replace
router.go
router.back
router.forward
编程式导航
router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)
router.back()
router.forward()
router.getMatchedComponents
router.resolve
router.addRoutes
router.onReady
router.onError
注册一个回调,该回调会在路由导航过程中出错时被调用。注意被调用的错误必须是下列情形中的一种:
- 错误在一个路由守卫函数中被同步抛出;
- 错误在一个路由守卫函数中通过调用 next(err) 的方式异步捕获并处理;
- 渲染一个路由的过程中,需要尝试解析一个异步组件时发生错误。