Vue-Router基础知识点总结【vue系列】

Vue-Router

一. 认识路由

 1.什么是路由(理解)

  • 路由解释
    • 路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动
    • 路由中有一个非常重要的概念叫路由表
      • 路由表本质上就是一个映射表, 决定了数据包的指向
  • 路由器
    • 路由器提供了两种机制: 路由和转送.
      • 路由是决定数据包从来源目的地的路径
      • 转送将输入端的数据转移到合适的输出端

        

 

   

  路由是根据不同的ur地址展示不同的内容或页面;

  路由是一个比较广义和抽象的概念, 路由的本质就是对应关系

  2.后端路由阶段

  

  • 在早期的网站开发整个HTML页面是由服务器来渲染的
    • 服务器直接将渲染好对应的HTML页面, 响应给客户端展示
  • 后端路由
    • 浏览器在地址栏中切换不同的url时, 每次都向后台服务器发出请求, 服务器响应请求
    • 在后台拼接html文件传给前端显示, 返回不同的页面
    • 意味着浏览器会刷新页面,网速慢的话说不定屏幕全白再有新内容。后端路由的另外一个极大的问题就是 前后端不分离
  

 

   后端路由的缺点

  • 整个页面的模块由后端人员来编写和维护的, 不易维护
  • 通常情况下HTML代码和以及对应的后端逻辑代码会混在一起, 编写和维护都是非常糟糕的事情

 3.前端路由阶段

  • 前后端分离阶段:
    • 随着 Ajax 出现, 有了前后端分离的开发模式
    • 后端只提供 API 来返回数据, 前端通过 Ajax 获取数据, 通过 JS 将数据渲染到页面中
    • 这样做最大优点就是前后端责任清晰, 后端专注于数据上, 前端专注于交互和可视化上
    • 并且移动端 (ISO/Android) 出现后, 后端不需要进行任何处理, 依然使用之前一套 API 即可
  • 什么是SPA
    • SPA是 single page web application 的简称, 译为单页Web应用
    • 简单说 SPA 就是一个 web 项目只有一个 html 页面, 一旦页面加载完成, SPA 不会因为用户的操作进行页面的重新加载或跳转
    • 取而代之的是利用 JS 动态的变换 html 的内容, 从而模拟多个视图间跳转
  • 单页面富应用 (SPA)
    • 其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由
    • 也就是前端来维护一套路由规则
  • 前端路由的核心是什么呢?
    • 改变URL, 但是页面不进行整体的刷新

  

二. 前端路由的规则  

  1.URL的hash

  • URL的hash也就是锚点(#), 本质上是改变window.location的href属性
  • 我们可以直接赋值location.hash改变href, 但是页面不发生刷新

   

  2.HTML5的history模式

  • history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面
  • history.pushState()
    • 类似: 进栈出栈, 先进后出

    

  • history.replaceState()
  •    替换URL, 没有回退

  

  • history.back()
    • 回退到上一次的URL
  • history.forward()
    • 前进上一次的URL
  • history.go(Number)
    • Number: 前进或回退到指定的URL

  

三. Vue-Router基础 

  1.认识vue-router

  • vue-router是Vue.js官方的路由插件, 它和vue.js是深度继承的, 用于构建单页面应用 (官方文档)
  • vue-router是基于路由和组件的
    • 路由用于设定访问路径, 将路径和组件映射起来
    • 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换

  2.安装与使用vue-router

  • 步骤一: npm安装

    • npm install vue-router --save
  • 步骤二: 在模块工程中使用它(因为是一个插件, 所以通过Vue.use()来安装路由功能)

    ① 导入路由对象, 并且调用Vue.use(VueRouter)安装路由功能

    ② 创建路由实例, 并传入路由映射配置

    ③ 在主入口文件: 引入创建的路由实例, Vue实例中挂载路由实例

  1.配置Vue-Router (图示)
  

 

  •  步骤三: 使用vue-router
    • 创建路由组件

    • 配置路由映射(组件和路径映射的关系)

    • 使用路由 <router-link to="/path">和 <router-view>

  2.使用Vue-Router (图示)

  

  3.路由组件详解

  • <router-link>: 该标签是已经内置全局的组件, 它会被渲染成一个<a>标签

    • to="path": 该属性会被渲染为href属性
    • to="path": 属性的值会渲染为 # 开头的 hash 地址
      • path: 在路由中配置的 path 路径
  • <router-view>: 该标签会根据当前的路径, 动态渲染出相对应的组件

  • 在路由切换时, 切换的是<router-view>挂载的组件, 其他内容不会发生改变

四. 路由配置其他补充 

  1.路由的默认路径

  场景: 进入网站首页, 希望<router-view>渲染首页的内容
  • 在路由规则中添加默认路径的重定向
const routes = [
    {
      // 配置默认路径
      path: '/',
      // 重定向到/home路径
      redirect: '/home'
    }
]

  2.路径的History模式

   场景: 页面显示的URL, 不希望是哈希值带 #/home, 希望显示正常的URL: /home

  • VueRouter实例option中设置modehistory模式即可
// 创建VueRouter对象
const router = new VueRouter({
  routes,// 路由规则
  mode: 'history'// URL显示的模式
}) 

  3.router-link和配置路由的属性补充

  <route-link>其他的属性
  •   tag="": tab可以指定<router-link>组件渲染成什么元素
  • replace: 没有回退history记录, 前进没有效果
  • active-class="": 当<router-link>对应的路径匹配成功时, 会自动给当前元素添加一个router-link-activeclass, 设置active-class可以更改默认的名称
<!-- tag: 指定<router-link>组件渲染成什么元素 -->
<!-- replace: 没有history记录,前后键没有用 -->
<!-- active-class: 修改匹配成功默认添加的class类名 -->
<router-link to="/home" tag="button" replace active-class="active">首页</router-link>
<router-link to="/about" tag="button" replace active-class="active">关于页面</router-link>
  • 配置路由的属性: linkActiveClass
    • 作用: 当<router-link>对应的路径匹配成功时, 设置默认添加的类名
const router = new VueRouter({
  routes,// 路由的映射规则
  mode: 'history',// 模式
  linkActiveClass: 'active'// 设置默认匹配添加地类
})  

  4.编程式导航

  场景: 没有使用<router-link>全局组件, 来跳转URL
  • this.$router.push('path'): 来实现跳转URL, 有回退history记录
  • this.$router.replace('path'): 来实现跳转URL, 没有回退history记录
methods: {
    home() {
      // 没有使用<router-link>全局组件,来跳转URL,如何实现
      // this.$router.push('/home') // 有回退记录
      this.$router.replace('/home') // 没有回退记录
    },
    about() { 
     // this.$router.push('/about') 
     this.$router.replace('/about') 
   }
  }

  

  5.动态路由匹配

  
  • 某些情况, 我们需要动态的来设置path路径, 比如进入用户页面, 希望显示的是如下路径

    • /user/aaa 或 /user/bbb
    • 除了有前面的 /user 之外, 后面还跟上了用户的ID
    • 这种 path 和 Component 的匹配关系, 称之为动态路由(也是路由传递数据的一种方式)
  • 动态路由匹配步骤

    • 1.配置动态路由参数
const routes = [{
  path: '/user/:userId',
  component: User
}]
    • 2.在APP.vue组件中传递参数
    • 3.路由组件中通过 $route.params 获取路由参数

  图示

 

五. 路由懒加载

  1.认识路由懒加载

  

  • 官方解释
    • 当打包构建应用时, JavaScript包会变的非常大, 影响页面加载
    • 如果我们能把不同路由对应的组件分割成不同的代码块, 然后当路由被访问的时候才加载对应组件, 这样就更高效了
  • 为什么使用路由懒加载?
    • 我们打包后的文件一般情况都是放在一个js文件当中, 必然这个文件会非常大
    • 如果我们一次性从网络请求下来这个文件, 可能花费很长时间, 甚至浏览器出现短暂白屏状况
    • 如何避免这种情况: 使用路由懒加载就可以了
  • 路由懒加载做了什么?
    • 路由懒加载的主要作用就是: 将路由对应的组件打包成一个个的js代码块
    • 只有这个路由被访问到的时候, 才加载对应的组件

 

  2.使用路由懒加载

  • 方式一: 结合Vue的异步组件和Webpack的代码分析
    • const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
  • 方式二: AMD写法
    • const About = resolve => require(['../components/About.vue'], resolve);

 

  • 方式三: ES6中, 我们有更加简单的写法来组织Vue异步组件和Webpack的代码分隔
    • const Home = () => import('../components/Home.vue')

 

  • 打包后效果图

        

六. 路由嵌套 

  1.认识嵌套路由

  • 在 home 页面中, 我们通过 /home/news 和 /home/message 访问一些内容
  • 在一个路径映射另一个组件, 访问这两个路径也会分别渲染两个组件
  • 路径和组件的关系如下:

  

  2.嵌套路由实现  

  • 1.创建组件
  • 2.在路由映射规则中, 配置嵌套路由: children: [{},{}]
  • 3.在需要嵌套该组件的页面中, 使用 router-link 和 router-view
  •  

     

  3.嵌套路由的默认路径

  • 嵌套的路由也可以设置默认路径
  •   const routes = [
      {
        path: '/home', 
       component: Home,
        // 配置嵌套路由
          children: [ 
       { 
         // 嵌套路由的默认路径
          path: '',
          redirect: 'news'
        }, 
       { 
         path: 'news', 
         component: News
        },
        {      path: 'message',
          component: Message
        }] 
     }]

     

七. query获取参数 

  1.query获取

  • 1.创建新的组件 Profile.vue
  • 2.配置路由映射
  • 3.在 APP.vue 添加跳转的 <router-link>

  

<!-- 1. APP.vue 参数的传递 -->
<router-link :to="{path: '/profile',query: {
  name: 'wuyifan', 
 age: 18,
  height: 1.88}}">档案</router-link>
<!-- 2.  Profile.vue 获取query参数 -->
 <h3>{{$route.query}}</h3>

  图示

  

  2.传递参数的方式 

  • 传递参数主要有两种类型: params和query
  • params
    • 配置路由path: /user/:userId
    • 传递的方式: 在path后面拼接上需要传递的值
    • 获取传递的参数: $route.params.userId
  • query
    • 配置路由path: /profile (普通配置)
    • 传递的方式: {path: '/profile', query: {name: 'yifan'} }
    • 获取传递的参数: $route.query.name
  当你不使用<router-link>来实现跳转
  •   
    this.$router.push({ 
           path: '/profile', 
           query: { 
             name: 'yifan',
              age: 18, 
             height: 1.88 
           }
          })

 

  3. router 和 route的区别

  • $router$route区别
    •   $router是VueRouter实例, 对路径相关导航操作
    •   route是当前path映射的组件对象(当前活跃的路由对象), 可以获取path, query参数等
    •  

       

八. 导航守卫⚔

  1.认识导航守卫

  官方解释: vue-router提供的导航守卫主要用来通过跳转或取消的方式导航守卫

  

  导航守卫
  • 导航守卫就是路由跳转过程中的一些钩子函数, 路由跳转是一个大的过程, 这个大的过程前后中等等细小的过程, 在每个过程都有一个函数, 这个函数能够让你操作一些其他的事情, 这就是导航守卫
  • vue-router提供了beforeEachafterEach的钩子函数, 它们会在路由即将改变前和改变后触发

  全局钩子函数

  可以直接在路由配量文件router.js里编写代码逻辑, 可以做一些全局性的路由拦截
 
// 全局前置守卫router.beforeEach((to, from, next) => { 
  // to: Route:即将要进入的目标路由对象
 // from: Route:当前导航正要离开的路由
      // 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed (确认的) next();
});
// 全局后置守卫router.afterEach((to, from) => {
    console.log(to.path);
});

 

  2.导航守卫使用

  • 考虑一个需求: 在一个SPA应用中, 如何修改网页标题
    • 第一应该想到在每一个路由对应的组件.vue文件中, 通过mounted生命周期函数, 对标题修改
    • 但是当页面比较多是, 这种方式不易维护(因为需要在多个页面执行类似的代码)
    • 有没有更好的方法呢? 使用导航守卫即可
  • 在路由配置文件中使用导航守卫, 修改网页标题
  
// 在钩子当中定义一些标题, 可以利用meta来定义const routes = [
    {
        path: '/user/:userId',
        component: User,
        meta: { 
           title: '用户'        
        }
    },
    {
        path: '/profile',
        component: Profile,
        meta: {
            title: '档案' 
       }
    }]

    // ------导航守卫(guard)-----------
    router.beforeEach((to, from, next) => {
        // 从from跳转到to
      // from: 将要进行跳转的当前$route对象 (跳转前的一些操作)
      // to: 跳转后$route对象 (跳转后的一些操作)
      // next(): 调用该方法后, 才能进入下一个钩子
       document.title = to.matched[0].meta.title;
      next()
})

 

  3.全局后置钩子

  你也可以注册全局后置钩子, 然而和守卫不同的是, 这些钩子不会接受next函数也不会改变导航本身 

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

 

  4.路由独享钩子函数

  可以做一些单个路由的跳转拦截。在配量文件编写代码即可

const router = new VueRouter({
  routes: [
    { 
     path: '/foo', 
     component: Foo,
      beforeEnter: (to, from, next) => {
        // ... 
     }
    }
  ]})

 

  5.组件内钩子函数

  更细粒度的路由拦截, 只针对一个进入某一个组件的拦截

  

const Foo = {
  template: `...`,
    beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当钩子执行前,组件实例还没被创建
  },
   beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
   beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  } 
    
 
}

 

  钩子函数使用场景

  其实路由钩子函数在项目开发中用的并不是非常多,一般用于登录状态的校验,没有登录跳转到登录页;权限的校验等等。当然随着项目的开发进展,也会有更多的功能可能用钩子函数实现会更好,我们知道有钩子函数这个好东西就行了,下次遇到问题脑海就能浮现,噢,这个功能用钩子实现会比较棒。我们的目的就达到了。

九. keep-alive组件

  1.页面缓存

  • 在Vue构建的单页面应用(SPA)中, 路由模块一般使用vue-router
  • vue-router不保存组件被切换的状态, 它进行push或replcae时, 旧组件会被销毁, 新组建会被创建, 再走一遍完整的生命周期
  • 但是有的时候, 我们有一些需求,: 比如返回到跳转前用户点击的列表页面, 但是当我们返回的时候没有之前的记录,对于这种页面缓存需求, 我们可以使用keep-alive组件来解决

  2.keep-alive组件

  • keep-alive 是 Vue 内置的一个组件, 可以使被包含的组件保留状态, 或避免重新渲染
    • 两个非常重要的属性:
    • inclue: 值是字符串或正则表达, 只有匹配的组件会被缓存
    • exclue: 值是字符串或正则表达, 任何匹配的组件都不会被缓存
    • 千万注意: 字符串匹配的是Vue组件中name属性, 如果没有配置name属性 keep-alive 将不会生效
  • 使用keep-alive: 在keep-alive包裹中的视图组件都会被缓存
  • <!-- Profile,User是 Vue 组件中的name属性(千万注意,如果没有配置将不会生效) -->
    <keep-alive exclude="Profile,User">
      <router-view></router-view>
    </keep-alive>

    另外:activated,deactivated这两个生命周期函数一定是要在使用了keep-alive组件后才会有的,否则则不存在

作者:风不识途

链接:https://juejin.im/post/6857124868359061512
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

posted @ 2020-08-06 17:33  正在变厉害的路上  阅读(464)  评论(0编辑  收藏  举报