# 基本使用
// ../router/index.js | |
import Vue from 'vue'; | |
import VueRouter from 'vue-router'; | |
import routes from 'routes' | |
// 注册路由 | |
Vue.use(VueRouter); | |
export default new VueRouter({ | |
mode:'history', | |
routes | |
}) | |
-------------- | |
//routes.js 路由表文件 | |
import Home from '../pages/Home' | |
export default [ | |
{ | |
path:'/', | |
component:Home | |
}, | |
{ | |
path:'/', | |
redirect:Home // 默认选中 Home 路由组件 | |
} | |
] | |
----------- | |
//main.js 在全局文件中使用路由器 | |
import Vue from 'vue'; | |
import router from '../Router'; | |
new Vue({ | |
name:'app', | |
eq:'#app', | |
components:{ | |
router | |
} | |
}) |
当我们在 main.js
中注册了 router
,我们就可以在任何一个组件(包括非路由组件)中使用 $route
和 $router
对象了。
$route
对象是局部路由信息对象,它包含了当前路由组件里的信息,包括 params
、 query
参数等等,我们可以用它来获取路由组件的参数
$router
对象是全局的路由器对象,全局就一个。它包含了很多属性和方法(push、replace、go 等等),可以让整个应用都可以拥有路由功能。编程式导航就利用了这个对象来实现动态跳转。
<router-view>
标签标明了切换路由组件时,路由组件的显示位置。路由导航有两种模式:一种是声明式路由导航,另一种是编程式路由导航。使用 <router-link to="path">
显示声明路由导航位置就是声明式导航,这种方式适合固定部位导航如顶部的注册登录按钮等,一旦页面要生成的声明式导航过多那么页面就会变的十分卡顿。当链接过多时推荐使用编程式导航来生成导航链接,编程式导航还可以利用事件委托进一步优化页面性能。使用编程式导航时我们只需要给 DOM 元素添加 click
事件,在这个事件触发的函数里我们可以用 $router.push
或 $router.replace
这两个函数完成路由跳转。这两种方式的唯一的区别就是 push
方法生成的链接没有历史浏览记录,无法回退。当需要回退功能时可以使用 replace
。
# 路由模式
vue-router
有两种路由方式,分别是 hash
模式和 history
模式。一般默认使用 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。在 hash
模式中, URL
路径上会有一个 #
标识符, #
标识符和后面的 URL
片段被称为 hash
。它有以下一些特点:
- 在第一个
#
后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。 - 单单改变 #后的部分,浏览器只会滚动到相应位置,不会重新加载网页。
- 每一次改变 #后的部分,都会在浏览器的访问历史中增加一个记录,使用 "后退" 按钮,就可以回到上一个位置。
- 可通过 window.location.hash 属性读取 hash 值,并且 window.location.hash 这个属性可读可写。
- 使用 window.addEventListener ("hashchange", fun) 可以监听 hash 的变化
而 history
模式是采用 HTML5
标准的 History。当你使用 history
模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id
,路径中不会出现 #
。这种模式需要后台的支持,若后台没有做相应处理,则该种模式直接使用 URL
路径访问会无法访问到对应资源。
两种模式的区别:
hash
模式相对history
模式兼容性更好点hash
模式中#
以后的东西都不会被当作路径发送给后端服务器,history
模式里整个url
都会被当作请求路径发送给后端服务器,这可能导致刷新页面时,如果没有专门配置 404 页面会导致请求了没有的路径时页面空白history
模式需要后端服务器的支持
# 缓存路由组件
我们都知道当切换路由时原本的路由会被销毁,有时候我们不希望切换路由时原组件被销毁。这时就可以使用路由缓存技术。我们需要在放置 <router-view>
的组件里使用 <keep-alive>
包裹,这样所有在该视图里展示的路由组件都会被缓存。若我们不想所有路由组件被缓存我们可以使用 <keep-alive include="组件名">
来指定缓存的路由组件,需要缓存多个时可以使用数组的形式 <keep-alive :include="['组件名1','组件名2']">
。让不展示的路由组件保持挂载,不被销毁
# 两个路由组件独有的生命周期钩子
- activeated:路由组件被激活(展示)时触发
- deactivated:路由组件失活(隐藏)时触发
当路由组件被 keep-live
但又不被展示时,我们可以使用这两个钩子来做一些事情。例如停用定时器等等
# 路由守卫
路由守卫可以分为三大类:全局路由守卫、独享路由守卫和组件路由守卫。路由守卫使用的场景通常是需要鉴权的时候,例如有些页面需要登录才能查看,有些页面只能从规定的页面去跳转。
全局路由守卫和独享路由守卫的概念是类似的,只不过全局路由守卫是作用于全局,任何一个组件跳转都要通过全局路由守卫。 beforeEach
和 afterEach
就是提供给我们的两个用于操作组件路由匹配动作前后的函数,其中在所有的守卫中仅 afterEach
没有 next
参数,其它守卫都有 to、from、next
这三个参数。** 这两个函数我理解为类似于 beforeMonted
和 mounted
这两个生命周期钩子,它们分别在路由规则匹配前后工作。** 而独享路由守卫仅有一个匹配前的函数 beforeEnter
供我们使用。
组件路由守卫有三个函数 beforeRouterEnter
、 beforeRouteUpdate
和 beforeRouteLeave
。组件路由守卫都是在组件通过路由规则匹配才能生效的,若不是通过路由规则跳转的则守卫不会被执行。
beforeRouterEnter
在渲染该组件的对应路由被 confirm 前调用,并且不能获取组件实例this
因为当守卫执行前,组件实例还没被创建。beforRouterUpdate
在当前路由改变,但是该组件被复用时调用。举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。它里面可以访问组件实例this
。beforeRouteLeave
导航离开该组件的对应路由时调用,这里的导航离开指的是不显示该组件要去往其它组件时的场景, 可以访问组件实例this