vue-router那些事

伴随着前端各种框架的出现,SPA(single page web application)应用势不可挡,伴随着的就是前端路由

SPA最主要的特点就是在前后端分离的基础上加了一层前端路由

前端路由的核心

改变URL, 但是页面不进行整体的刷新。那问题就来了,我该怎么做?

  1. URL的hash

URL的hash也就是锚点(#),本质上是改变window.location的href属性。

我们可以通过直接赋值location.hash来改变href,但是页面不发生刷新

  1. HTML5的history模式:pushState

    history接口是HTML5新增的, 他有5种模式改变URL而不刷新页面

    • history.pushState()

    • history.replaceState()

    • history.back() | history.forward() | history.go()

      • history.back() 等价于 history.go(-1)
      • history.forward() 等价于 history.go(1)

    在讲解vue中使用vue-router改变URL不刷新页面之前,先看一下

vue-router的使用

  1. 安装vue-router
npm install vue-router --save
  1. 在模块化工程中使用它(因为是一个插件,所以通过Vue.use()来挂载插件并使用)
    1. 导入路由对象,并且调用Vue.use(VueRouter)
    2. 创建路由实例,并且传入路由映射配置
    3. 在Vue实例中挂载创建的路由实例
  2. 使用vue-router的步骤
    1. 创建路由组件
    2. 配置路由映射:组件和路径映射关系
    3. 使用路由:通过 <router-link>和<router-view>

  • <router-link>该标签是一个vue-router中已经内置的组件,他会被渲染成一个<a>标签
  • <router-view>该标签会根据当前的路径,动态渲染出不同的组件
  • 在路由切换时,切换的是<router-view>挂载的组件,其他内容不会发生改变
  1. 路由的默认路径

默认情况下,进入网站的首页,我们希望<router-view>渲染首页的内容。但是我们的实现中,默认没有显示首页组件,必须让用户点击才可以

  • 我们只需要多配置一个路由映射关系就可以了

![12](/Volumes/Macintosh HD - 数据/Users/liubi_chaos_g/Pictures/12.png)

  • path配置的是根路径 /
  • redirect是重定向,也就是我们将根据路径重定向到/home的路径下
  1. HTML5的history模式
  • 前面说过改变路径的方式有两种
    • URL的hash
    • HTML5的history
    • 默认情况下,路径的改变使用的URL的hash
  • 如果希望使用HTML5的history模式,配置如下:

router-link补充

前面的<router-link>中,我们只是使用了一个属性to,用于指定跳转的路径

<router-link>还有一些其他属性:

  • tag:tag可以指定<router-link>之后渲染成什么组件,比如<router-link to='/home' tag='li'>会渲染成一个<li>元素,而不是<a>
  • replace:replace不是留下history记录,所以指定replace的情况下,后退键返回到上一个页面中
  • active-class:当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class,设置active-class可以修改默认的名称
    • 在进行高亮显示的导航菜单或者底部tabbar时,会使用该类

    • 但是通常不会修改类的属性,会直接使用默认的router-link-active即可

    • 修改linkActiveClass,可以通过router实例的属性进行修改

路由代码跳转

有时候,页面的跳转可能需要执行对应的JavaScript代码,这个时候,就可以使用第二种跳转方式了

代码修改如下图

动态路由

在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是这样的路径/user/aaa或、user/mmm

这种path和Component的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)

  • 路由代码
  {
    path: '/user/:id',
    component: User
  }
  • 组件代码
<template>
  <div>
    <h2>我是用户页面</h2>
    <p>用户页面有下面这些信息,通过params传过来的</p>
    <h4>{{$route.params.id}}</h4>
  </div>
</template>
  • 父组件代码
<router-link :to="'/user/' + id">用户</router-link>
或者
<router-link to="/user/zhangsan">用户</router-link>
  • 效果图

路由的懒加载

  • 路由的懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块
  • 只有在这个路由被访问到的时候,才加载对应的组件

如图:没有使用懒加载,最终编译的文件只有四个(使用vue4.0)

如图:使用了路由懒加载,每个路由文件都会单独编译成一个文件

  • 懒加载的方式

    • 方式一:结合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')
    

嵌套路由

注意点:

  • 配置嵌套路由的映射关系时,path不需要添加/
  • 路由跳转时,需要填写完整的路由映射;如home下面有个news嵌套路由,代码<router-link to="/home/news"></router-link>
  // 路由配置
	{
    path: '/home',
    component: Home,
    children: [
      {
        path: '',
        redirect: 'message'
      },
      {
        path: 'message',
        component: Message
      },
      {
        path: 'news',
        component: News
      }
    ]
  }
<template>
  <div>
    <h2>我是首页</h2>
    <p>我是首页的内容</p>
    <router-link to="/home/message">未读消息</router-link>
    <router-link to="/home/news">整点新闻</router-link>

    <router-view></router-view>
  </div>
</template>

传递参数的方式

  • 传递参数主要有两种类型:params和query

  • params的类型

    • 配置路由格式:/router/:id
    • 传递的方式:在path后面跟上对应的值
    • 传递后形成的路径:/router/123ab
  • query的类型

    • 配置路由格式:/router,也就是普通配置
    • 传递的方式:对象中使用query的key作为传递方式
    • 传递后形成的路径:/router?id=123&age=23
  • 方式一:<router-link>

<router-link :to="{ path: '/profile', query: { name: 'chaos', age: 11, hobby: 'music' } }">档案</router-link>
  • 方式二:js代码
    toProfile() {
      this.$router.push({
        path: '/profile',
        query: {
          name: 'chaos',
          age: 11,
          hobby: 'girl'
        }
      })
    }
  • 获取参数
<template>
  <div>
    <h2>我是档案页面,我会将传递过来的参数展示到下面</h2>
    <p>这是通过params传递过来的参数{{$route.params}}</p>
    <p>这是通过query传递过来的参数{{$route.query}}</p>
  </div>
</template>

$router和$route的区别

  • $router是VueRouter的实例,想要导航到不同的URL,则使用$router -- 路由的调度者
  • $route为当前router跳转对象,路由本身;可以获取name、path、query、params等

导航守卫

  • vue-router提供的导航守卫主要用来监听路由的进入和离开的

  • vue-router提供了beforeEach和afterEach的钩子函数,他们会在路由即将改变前和改变后触发

  • 我们可以利用beforeEach来完成标题的修改

    • 首先,我们可以在路由映射中定义一些标题,可以利用meta来定义
    • 其次,利用导航守卫,修改标题
      {
        path: '/home',
        component: Home,
        meta: {
          title: '首页'
        },
        children: [
          {
            path: '',
            redirect: 'message'
          },
          {
            path: 'message',
            component: Message
          },
          {
            path: 'news',
            component: News
          }
        ]
      },
      {
        path: '/about',
        component: About,
        meta: {
          title: '关于'
        }
      },
    
    router.beforeEach((to, from, next) => {
      console.log(to)
      document.title = to.matched[0].meta.title
      next()
    })
    
  • 导航钩子的三个参数解析

    • to:即将要进入的目标的路由对象
    • from:当前导航即将要离开的路由对象
    • next:调用该方法后,才能进入下一个钩子

keep-alive

  • keep-alive是vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。有两个非常重要的属性(属性里面不要随便加空格,造成匹配错误
    • include - 字符串或正则表达式,只有匹配的组件才会被缓存
    • exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
  • router-view也是一个组件,如果直接被包在keep-alive里面,所有路径匹配到的试图组件都会被缓存
posted @ 2020-06-17 17:13  Chaos_G  阅读(291)  评论(0编辑  收藏  举报