【笔记】vue-router

242 阅读6分钟

vue cli 安装

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统

步骤

(首先要安装 nodejs)

  • 全局安装 vue-cli
npm(cnpm) install -g vue-cli
  • 初始化项目(进入目录)
vue init webpack my-project
  • 进入项目
cd my-project
  • 安装依赖
npm install
  • 启动项目
npm run dev

内容

目录结构
目录结构
  • build 项目构建(webpack)相关代码
  • config 配置目录,包括端口号等
  • node_modules npm 加载的项目依赖模块
  • src
    • assets 放置图片
      • logo.png
    • components 组件
      • HelloWorld.vue
    • router 路由文件
      • index.js
    • App.vue 项目入口文件
    • main.js 项目核心文件
  • static 静态资源,字体、图片等
  • test 初始测试目录
  • index.html 首页入口文件
  • package.json 项目配置文件

vue-router

路由管理器,它和 Vue.js 的核心深度集成,让构建单页面应用(SPA)变得易如反掌。

将组件映射到路由,然后告诉 Vue Router 在哪里渲染它们

SPA

SPA(single-page application)单页面跳转仅刷新局部资源,js、css 仅加载一次

  • 优点
    • 避免不必要的跳转和重复渲染
    • SPA 相对服务器压力较小
  • 缺点
    • 首次加载用时较多
    • 不利于 seo 优化
    • 后退前进功能没法用

安装路由

  • 安装
npm(cnpm) install --save vue-router
  • 引用
//main.js
import Router from 'vue-router'
Vue.use(Router)
  • 配置路由文件,在 vue 实例中注入
//main.js
var router = new Router({
 routes: [
    {
      path: '/',//指定跳转路径
      name: 'HelloWorld',
      component: HelloWorld //指定跳转组件
    }
  ]
})
new Vue({
el: '#app',
router: router,
components: {App},
template: '<App/>'
})

//引入组件
import HelloWorld from './components/HelloWorld'
router配置
router配置

router-view

渲染路径匹配到的视图组件

<router-view></router-view>

router-view0 router-view1 router-view2 router-view展示

动态路由

有个 demo 组件,id 不同的用户都要使用这个组件渲染

  1. 填写路由参数 动态路由0
  2. 获取当前路由参数

路由设置路径参数,对应的值会设置到$router.params(包含了动态片段和全匹配片段) 动态路由1

  1. 测试 动态路由展示
  2. 响应路由的参数的变化
  • 利用 watch 监听$route 对象 watch监听

  • 响应路由参数的变化,输出信息 watch监听展示

嵌套路由

  1. 要在 children 配置被嵌套的路由,嵌套路由 path 不加/ router-link0
  1. router-link 指定目标 router-link1

  2. 在 APP.vue 引入 demo 视图组件 router-view0

  3. 点击链接显示 demo1 和 demo2,注意地址栏变化 router-link2 router-link展示1 router-link展示2

多个视图

  1. 在 components 配置
多个视图1
多个视图1
  1. 通过 router-link 的 name 名指定 多个视图2

  2. 显示 多个视图展示

路由组件传参

使用 props 将组件和路由解耦

  • 组件与$route 耦合 动态路由0 动态路由1 动态路由展示

  • props 解耦

将 props 设置为 true,$route.params 将会被设置成组件属性 props解耦0 propprops解耦1 props解耦展示

router-link

支持用户在具有路由功能的应用中导航

  • to 属性指定目标地址
<router-link to="/"></router-link>
router-link1
router-link1

比较<router-link><a href=''>链接

  • 表现行为一致
  • history 模式下,router-link 会守卫点击事件,让浏览器不再重载页面
  • history 模式下使用 base 选项之后,所有 to 属性都不需要写 base base1 base展示1 base展示2

router-link 传参

<router-link :to=''>

  1. path 后加/:+传递参数 router-link-to0

  2. :to 传递一个对象 router-link-to1 router-link-to展示0

  1. 两种格式
  • params 方式
<router-link :to="{name: 'demo1',params: {demo1msg: '这是demo1'}}">demo1</router-link>

router-link-to2 router-link-to展示1

  • query 方式
<router-link :to="{path:'/demo2',query: {demo2msg: '这是demo2'}}">demo2</router-link>
router-link-to展示2
router-link-to展示2

重命名

redirect

将 demo2 重定向到 demo,点击 demo2 链接显示的是 localhost:8080/#/demo redirect0 redirect1

别名

alias

/demo2 的别名是/demo7,当用户访问/demo7 时,url 保持的是/demo7,路由匹配的是/demo2,用户访问显示的是 demo2 的页面

  1. 将 alias 设置为 demo7 alias0
  2. 将 router-link 的 to 属性指定到/demo7 !alias1
  3. 页面显示的是 demo2 的网页,地址是 demo7
alias展示
alias展示

编程式导航

router.push()

<router-link :to=''>作用相同,向 history 添加一个新的记录

this.$router.push()
  1. this.$router.push()在方法上调用
  2. 点击 demo1 出现视图,但是地址栏未发生变化
  • http://localhost:8080/#/demo
  • 后退时回到之前的 url
  • http://localhost:8080/#/demo/demo1
  • http://localhost:8080/#/demo(这是之前的url)

router.replace()

替换当前 history 记录

this.$router.replace()

  • http://localhost:8080/#/demo
  • 后退时不会回到之前的 url
  • http://localhost:8080/#/demo/demo1
  • http://localhost:8080/#/(这是之前的url)

router.go()

在 history 记录中向前或后多少步

this.$router.go(-1)
  • http://localhost:8080/#/
  • http://localhost:8080/#/demo
  • 点击 demo2: http://localhost:8080/#/demo/demo2
  • 点击 back: http://localhost:8080/#/demo
  • http://localhost:8080/#/

两种模式

hash 模式

默认使用 URL 的 hash 来模拟一个完整的 URL,当 URL 改变时,页面不会重新加载

  • 地址栏中包括#符号,http://localhost:8080/#/demo,hash值为#/hello
  • hash 虽然出现在 url 中但不会被包括在 http 请求中,因此不会重新加载页面

history 模式

利用 history.pushState API 来完成 URL 跳转而无需重新加载页面

两种模式比较

  • hash 可以支持低版本浏览器和 IE
  • history 需要后台配置支持

导航守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航,监听路由变化

参数或查询的改变并不会触发进入/离开的导航守卫

全局导航(放在 main.js 文件)

监听整个路由变化

router.beforeEach

全局前置守卫

router.beforeEach((to, from, next) => {
  /* 必须调用 `next` */
})

router.beforeResolve

全局解析守卫,在导航被确认前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

router.beforeResolve((to, from, next) => {
  /* 必须调用 `next` */
})

router.afterEach

全局后置守卫,不接受 next 函数也不会改变导航本身,可以做一些用户提醒

router.afterEach((to, from) => {})

路由独享的守卫(index.js)

监听某个路由变化

beforeEnter

router.beforeEnter((to, from, next) => {
  /* 必须调用 `next` */
})

组件内守卫

监听路由组建的路由变化

beforeRouteEnter

组件内前置守卫

  • 不能获取组件实例 this
  • 因为当守卫执行前,组件实例还没被创建
  • 通过*next(vm=>{})*访问组件实例
  • 是支持给 next 传递回调的唯一守卫
 beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
  }

beforeRouteUpdate

组件内更新守卫

  • 可以访问组件实例 this
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
  }

beforeRouteLeave

组件内后置守卫, 通常用来禁止用户在未保存修改前突然离开

  • 可以访问组件实例 this
beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用

  }

完整导航流程

  1. 导航被触发
  2. 在失活的组件里调用离开守卫
  3. 调用全局的 beforeEach 守卫
  4. 重用的组件里调用 beforeRouteUpdate
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫
  9. 导航被确认
  10. 调用全局的 afterEach 钩子
  11. 触发 DOM 更新
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数