Open tomoya06 opened 3 years ago
Vue Router是使用Vue开发SPA时常用的前端路由管理系统。与传统的页面跳转相比,SPA的区别在于:
在vue-router开发的SPA中,页面的切换的切换实际是路径之间的切换,引起组件的切换,从而实现了SPA对页面跳转的要求:不刷新或重新获取页面就能完成页面跳转。
在SPA中,前端路由描述的是 URL 与 UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。
要实现前端路由,需要解决两个核心问题:
Vue router支持两种路由模式,分别是hash模式(默认)和history模式。两种模式对核心问题2的解决原理分别如下。
hash 模式使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
hash模式通过 hashchange 事件 来监听 URL 的变化,改变 URL 的方式只有这几种:
window.location
History API提供了popState事件,可以用来监听活动历史记录条目更改。另外提供了 pushState和 replaceState 两个方法,这两个方法改变 URL 的 path 部分不会引起页面刷新。
popState
pushState
replaceState
popState的触发情况有些特殊:
pushState/replaceState
<a>
另外,使用history模式时,后端需要特别配置。参考router博客提供的方案
除了使用<router-link>创建 a 标签来定义导航链接,我们还可以借助 router的实例方法,通过编写代码来实现。
<router-link>
router
在 Vue 实例内部,你可以通过 $router 访问路由实例。可以调用this.$router.push() / .replace() / .go()方法来导航。
$router
this.$router.push() / .replace() / .go()
一个路由对象 (route object) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的路由记录 (route records)。
路由对象是不可变 (immutable) 的,每次成功的导航后都会产生一个新的对象。在多个地方可以出现,参考API文档。
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
const router = new VueRouter({ routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] })
现在像 /user/foo 和 /user/bar都将映射到相同的路由。
/user/foo
/user/bar
注意,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route对象,或者使用 beforeRouteUpdate导航守卫。
$route
beforeRouteUpdate
如果想匹配任意路径,我们可以使用通配符 (*),含有通配符的路由应该放在最后,这样就可以捕获404错误。
*
有时候同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
Vue Router 原理解析
简介
Vue Router是使用Vue开发SPA时常用的前端路由管理系统。与传统的页面跳转相比,SPA的区别在于:
在vue-router开发的SPA中,页面的切换的切换实际是路径之间的切换,引起组件的切换,从而实现了SPA对页面跳转的要求:不刷新或重新获取页面就能完成页面跳转。
前端路由
在SPA中,前端路由描述的是 URL 与 UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。
要实现前端路由,需要解决两个核心问题:
实现原理
Vue router支持两种路由模式,分别是hash模式(默认)和history模式。两种模式对核心问题2的解决原理分别如下。
hash mode
hash 模式使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
hash模式通过 hashchange 事件 来监听 URL 的变化,改变 URL 的方式只有这几种:
window.location
改变URLhistory mode
History API提供了
popState
事件,可以用来监听活动历史记录条目更改。另外提供了pushState
和replaceState
两个方法,这两个方法改变 URL 的 path 部分不会引起页面刷新。popState的触发情况有些特殊:
pushState/replaceState
方法或点击<a>
标签改变 URL 不会触发 popstate 事件,需要拦截 pushState/replaceState的调用和<a>
标签的点击事件来检测 URL 变化另外,使用history模式时,后端需要特别配置。参考router博客提供的方案
API
编程式的导航
除了使用
<router-link>
创建 a 标签来定义导航链接,我们还可以借助router
的实例方法,通过编写代码来实现。在 Vue 实例内部,你可以通过
$router
访问路由实例。可以调用this.$router.push() / .replace() / .go()
方法来导航。路由对象
一个路由对象 (route object) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的路由记录 (route records)。
路由对象是不可变 (immutable) 的,每次成功的导航后都会产生一个新的对象。在多个地方可以出现,参考API文档。
动态路由匹配
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
现在像
/user/foo
和/user/bar
都将映射到相同的路由。注意,当使用路由参数时,例如从
/user/foo
导航到/user/bar
,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化)
$route
对象,或者使用beforeRouteUpdate
导航守卫。404路由捕获
如果想匹配任意路径,我们可以使用通配符 (
*
),含有通配符的路由应该放在最后,这样就可以捕获404错误。有时候同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。