⑥ vue-router

  • 多页面应用 MPA(Multiple Page Application)

  • 单页面应用 SPA(Single Page Application)

1 安装和引入

script 标签引入

在 Vue 后面加载 vue-router,它会自动实现安装

  <script src="./lib/vue.js"></script>
  <script src="./lib/vue-router.js"></script>

npm 方式(推荐)

  • Vue-Router 是通过插件的形式来扩展 Vue 的功能,所以要使用它,必须要通过 Vue.use() 方法安装路由功能
  import Vue from 'vue';
  import VueRouter from 'vue-router';

  // 调用Vue.use手动安装,之后才能在实例中通过this.$route访问
  Vue.use(VueRouter);

2 使用

2.1 步骤

  1. 引入 vue-router

  2. 使用 vue-router(script标签引入方式自动完成)

  3. 实例化 router 并配置参数

  4. router 实例注入到vue实例中

  5. 在组件中使用

2.2 参数配置

mode:路由模式

  • hash(默认)

  • history

需要后端配置,任意路径返回 index.html(IE9中会自动降级到hash模式)

routes:路由配置

核心配置,包含所有的页面配置

  • name:设置路由名称,方便执行路由跳转

  • path:访问这个页面的路径

  • component:指定路由组件(显示到<router-view/>中的组件)

  • components:在多视图组件中,给每个命名视图指定路由组件

    一般用于多个view-router的场景

  • props(Boolean|Object|Function):路由组件传参

  • redirect(String|Object|Function):重定向

  • children(Array):嵌套路由配置

    子路由一般使用相对路径的path

2.3 显示路由内容 <router-view/>

用于显示 component 路由组件内容

  • name 命名视图(默认:default)

2.4 导航(如何实现路由跳转)

2.4.1 声明式导航

利用内置组件标签来实现路由跳转

  • to(Sting|Object):设置目标路由的链接。点击后,跳到目标路由

  • tag:让 <router-link> 渲染成某种标签(默认:a)

  • active-class:匹配路由时 <router-link> 使用的类名

  • exact-active-class:精确匹配路由时 <router-link> 使用的类名

  • replace: 跳转到目标路由且不留下 history 记录

  • event: 触发路由的事件(默认:click)

2.4.2 编程式导航

利用 Router 实例(this.$router)的方法实现路由跳转

$router.push(location)
  this.$router.push('/home');
  // 等同于:<router-link to="/home"></router>

  // 对象
  this.$router.push({ path: '/home' })
  this.$router.push({ name:'Home' })
  // 等同于:<router-link :to="{name:'Home'}"></router>
$router.replace(location)

类似于 router.push(),唯一不同的是它不会向 history 添加新记录

$router.go(n) / $router.back() / $router.forward()

history 记录中向前或者后退多少步,类似 window.history.go(n)

2.5 路由传参

在组件中通过 this.$route 获取当前路由信息,包含传入的参数 params / query

2.5.1 跳转时传参

params
  • 通过 this.$route.params 获取,可通过动态路由、导航时传入等方式传入,刷新后参数不存在
  // params传参,只支持name方式跳转
  this.$router.push({ name: 'Goods', params: { id:123 }})

  // 动态路由传参
  this.$router.push('/goods/123')
query 传参
  • 通过 this.$route.query 获取,可通过路由导航时传入,刷新后参数依然存在
  this.$router.push('/goods?id=123')
  this.$router.push({ path:'/goods', query: { id: 123 }})
动态路由传入
  //路由组件
  const User = {
      template:`<div>{{$route.params.id}}</div>`
  }

  //路由配置
  routes:[{
      path:'/user/:id',
      component:User
  }]
  • 注意:当路由从 /user/zhoutest 导航到 /user/luotest,组件实例会被复用(因为两个路由都渲染同个组件 User,比起销毁再创建,复用则显得更加高效)因此不会执行组件的生命周期钩子函数。解决方案:

    • 利用 watch 监测 $route 对象变化

    • beforeRouteUpdate 路由守卫

  const User = {
    watch: {
      '$route' (to, from) {
      // 对路由变化作出响应...
      }
    },

    beforeRouteUpdate (to, from, next) {
      //to:目标路由
      //from:当前路由
      //一定要调用next()方法才可进入目标路由
    }
  }

2.5.2 定义时传参

props

以上通过 $route.params.id 获取参数方式较为繁琐,而且组件与路由高度耦合,可以使用 props 组件传参的方式解耦

Boolean 模式

如果 props 被设置为 true,内部会自动把 route.params 设置为组件属性

  const User = {
    props:['id'],
    template:`<div>{{id}}</div>`
  }

  routes:[{
    path:'/user/:id',
    component:User,
    props:true //等效于:<User v-bind="route.params"/>
  }]
Object 模式

如果 props 是一个对象,它会被按原样设置为组件属性(v-bind="{...}"),一般用于静态数据

  const User = {
    props:['myname'],
    template:`<div>{{myname}}</div>`
  }

  routes:[
    {
      path:'/user/:id',
      component:User,
      props:{myname:'zhoutest'}
      // 等效于:<User v-bind="{ myname: 'zhoutest' }"
    }
  ]
Function 模式

实现更灵活的参数传递,如可以把 query 参数传入组件

  const Settings = {
    props:['query'],
    template:`<div>{{query}}</div>`
  }

  routes:[
    {
      path:'/settings',
      component:Settings,
      props:(route) => ({ query: route.query.q }) 
    }
  ]

3 导航守卫(路由钩子函数)

3.1 路由跳转的过程

3.1.1 跨组件跳转

3.1.2 组件重用跳转

  • 每个路由守卫中都要调用 next()

3.2 路由守卫

3.2.1 全局守卫

所有的路由切换都会执行,一般写在路由配置文件中

  • router.beforeEach(fn)

    • to

    • from

    • next()

  • router.afterEach(fn)

    • to

    • from

3.2.2 路由独享的守卫

写在路由配置中

  • beforeEnter(fn)

    • to

    • from

    • next()

3.2.3 组件内的守卫

  • beforeRouteEnter(fn): 此时组件实例还没被创建,因此无法访问 this

    • to

    • from

    • next()

  • beforeRouteUpdate(fn)

    • to

    • from

    • next()

  • beforeRouteLeave(fn)

    • to

    • from

    • next()

posted on 2021-07-14 14:07  pleaseAnswer  阅读(61)  评论(0编辑  收藏  举报