VueRouter01 基础
Vue Router基础学习笔记。
安装
1 | npm install vue-router |
加载
需要使用Vue.use()
明确的安装路由
1 | // main.js |
基本使用
1 | <div id="app"> |
(1)用<router-link>
实现导航标签,在DOM中会被渲染为<a>
标签,to
属性指定链接
(2)用<router-view>
作为路由出口,路由对应的组件内容会被渲染到其中
(3)定义路由routes
,由对象组成的数组,对象至少包含的属性是path
和component
,其中path
和<router-link>
中的to
属性对应,to
属性如果不加/
则是以当前地址为基准的相对路径
(4)创建路由实例new VueRouter({routes})
(5)创建Vue实例时可以直接添加router
属性挂载路由
动态路由
在routes
数组的path
属性中,以:
开始后面的参数就是动态路径参数:
1 | const router = new VueRouter({ |
当访问/user/a
时,可以在组件中通过$route.params.id
获取到动态路径参数a
可以通过$route.query
获取URL中的查询参数,通过$route.hash
获取路由的hash值
动态路由间的跳转,比如从/user/a
到/user/b
,原组件实例会被复用,所以Vue实例的mounted
等生命周期钩子函数不会执行。如果想要响应参数变化有两种方法:
(1)watch
组件的$route
对象:
1 | const User = { |
(2)使用beforeRouteUpdate()
方法(2.2+)
1 | const User = { |
路由匹配
有时候,一个路径可以匹配多个多路,此时匹配的优先级就是按照路由的定义顺序,先定义的路由优先级最后,后面定义的路由就不会再匹配
可以使用通配符*
来匹配任意路径,由于上面提到的优先级,所以含有通配符的路由应该放在最后,一般用来匹配404
路由
1 | const router = new VueRouter({ |
使用了通配符后,可以通过$route.params
的pathMatch
属性获取URL通过通配符被匹配的部分。
除了通配符之外,vue-router支持很多高级的匹配模式,可以看这个例子来学习。
嵌套路由
<router-view>
是渲染路由内容的组件,最高级路由匹配到的组件会渲染到顶层的<router-view>
中。组件可以在内部包含自己的嵌套的<router-view>
,将路由选项中的children
属性中的组件渲染在其中
1 | const router = new VueRouter({ |
以/
开头的嵌套路径也会被当做根路径进行匹配。
嵌套路由如果要设置默认的子路由,子路有的path
可以设置为/
或者''
,但是父路由不能有的name
属性
(想要嵌套路由的<router-link>
的active-class
起作用,可以为自由路的默认路由设置redicet
:
1 | routes.find(v => v.path === '/demo38').children = [ |
编程式导航
除了使用<router-link>
来进行路由跳转之外,还可以通过$router
的实例方法实现编程式的导航
路由跳转可以使用$router.push
方法,它会向History栈添加新的记录,为用户点击后腿按钮提供后退功能
1 | router.push(location, onComplete?, onAbort?) |
第一个参数可以是字符串路径,也可以是一个描述地址的对象:
1 | // 字符串 |
如果提供了path
,param
虚选项会被忽略:
1 | const userId = '123' |
后两个参数是导航成功或终止后的回调函数,在3.1.0+版本后如果省略这两个参数,将会返回一个Promise
如果跳转时路由相同,只是参数发生变化(比如/user/:id
跳转),需要使用beforeRouteUpdate
来响应变化
除了router.push
,还可以使用router.replace
来进行跳转,不同的是router.replace
不会为History添加新纪录
还可以使用router.go(n)
,在History记录中向前或者后退多少步。
命名路由
在创建Router的实例时,在routes
数组内部对象增加name
属性,为路由设置名称
1 | const router = new VueRouter({ |
这样在<router-link>
的to
属性中,就可以使用name
属性来进行路由的匹配
1 | <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link> |
命名视图
在一个组件中,可以为<router-view>
添加name
属性,同时展示多个视图,没有设置name
的<router-view>
,默认为default
1 | <router-view class="view one"></router-view> |
在路由设置里面,需要使用components
在当前路由下渲染多个组件,不同组件对应不同name
的router-view
1 | const router = new VueRouter({ |
重定向和别名
重定向时在routes
数组的对象中添加rediect
属性:
1 | const router = new VueRouter({ |
redirect
的值可以是字符串,也可以是一个命名路由{ name: 'foo' }
,也可以是一个函数,返回值是字符串路径或者路径对象
注意导航守卫没有应用在跳转路由上,仅应用在目标上。
别名
别名与重定向不同,重定向会将URL进行替换,而设置了别名的路由,URL并不会改变:
1 | const router = new VueRouter({ |
当用户访问/b
时,URL显示为/b
,但是加载的组件是A
路由组件传参
在组件中使用$route
会使组件与对应路由高耦合,可以使用props
将组件合路由解耦:
1 | const User = { |
使用props
解耦,将props
设置为true
,那么$route.params
就会被设置为组件属性
1 | const User = { |
针对包含多个命名视图的路由,必须分别为每个命名视图添加props
选项:
1 | const router = new VueRouter({ |
如果props
是一个对象,那么会被原样设置为组件的属性,一般用做props
为静态的情况:
1 | const router = new VueRouter({ |
props
是也可以接受一个函数,参数是当前的路由对象route
:
1 | const router = new VueRouter({ |
访问/search?q=123
会将{query: 123}
作为属性传递给SearchUser
组件
应该尽可能保持props
函数为无状态的,如果需要状态来定义props
,请使用包装组件。
History模式
vue-router默认使用hash模式,使用URL的hash值来模拟一个完整的URL,当URL改变时,实际上改变的是#
后面的hash值,页面不会被重新加载
vue-router提供了history模式,它利用的是history.pushState
API来实现URL跳转而无需重新加载页面
1 | const router = new VueRouter({ |
这种情况下URL不会有#
,但是需要后台配置支持,因为如果后台没有配置,那么用户直接访问URL时,首先会经过后台的真正的路由,但是后台没有匹配的路由会返回404,所以应该在服务端增加一个覆盖所有情况的候选资源,如果URL匹配不到任何静态资源,就返回同一个index.html
,这个页面就是单页应用的容器页面
要注意,这个时候的后台无法响应404页面了,必须在前端给出404页面。