基本使用
// ../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