对vue-router 3个钩子的理解

一、router的配置页面index.js

    {
      path: '/child/:id',
      name: 'child',
      component: Child
    }

二 、child组件

<template>
  <div>
  </div>
</template>

<script>
  export default {
    name: "child",
    data() {
      return {
        a: ''
      }
    },
    beforeRouteEnter(to, from, next) {
      console.log('进入enter路由钩子')
      console.log(to)
      next()
    },
    beforeRouteLeave(to,from){
      console.log('进入leave路由钩子')
    },
    beforeRouteUpdate(to, from, next) {
      console.log('进入update路由钩子')
      console.log(to.params.id)
    }

  }
</script>

<style scoped>

</style>

三、parent组件

<template>
  <div>
    <button @click="al(1)">1111</button>
    <button @click="al(2)">2222</button>
  </div>
</template>

<script>
  import Child from '@/components/Child'

  export default {
    name: "parent",
    methods: {
      // al(id) {
      //   this.$router.push({
      //     name: 'child',
      //     params: {
      //       id: id
      //     }
      //   })
      // }
      al(id) {
        this.$router.push(`/child/${id}`)
      }
    },

  }
</script>

<style scoped>

</style>

那么可以通过点击parent中的按钮,调用router的push方法来通过router传递参数。

  • 首先我们点击 第一个btn 会发现在控制台输出

《对vue-router 3个钩子的理解》

  • 这个时候我们点击浏览器的后退 按钮 会发现在控制台输出

《对vue-router 3个钩子的理解》

  • 再次在parent页面点击btn2 查看控制台

《对vue-router 3个钩子的理解》
这里我们可能会疑惑,为什么我点击btn2的时候,为什么进入的会是update钩子,而不是enter钩子。

查看vue-router文档 会发现这是因为vue-router对重复的组件进行了复用,因为点击btn1的时候,child组件已经被加载了,那么再次点击btn2的时候,vue会复用child组件,所以这里出发的是update钩子。在vue2.2之前,都是通过watch 监听$route 来触发update的。

这里需要指出 在调用beforeRouteEnter和beforeRouteUpdate的时候,最后一定要调用next(),否则点击btn按钮,路由不会发生变化。

这里小弟的一些薄见,有问题欢迎大家指出 。

@太羽 看到你的问题 我这里新增一些 希望可以帮到你

  • 问题1: 如何配置子路由id参数,这个子路由参数和父路由参数的配置方法是

一样的,可以直接在children的path上面使用 :参数 的方法是传递参数。

    {
      path: '/parent',
      name: 'parent',
      component: Parent,
      children: [
        {
          path: 'child/:id',
          name: 'child',
          component: Child,
        }
      ]
    },

此时父组件 可以使用上面同样的方式来push参数

   this.$router.push(`/parent/child/${id}`)

同样的子组件可以在上面讲述的钩子函数中获取参数id的数值

子组件

    beforeRouteEnter(to, from, next) {
      console.log(`我是商品${to.params.id}`)
      next()
    },
    beforeRouteLeave(to, from) {
      console.log('进入leave路由钩子')
    },
    beforeRouteUpdate(to, from, next) {
      console.log(`update我是商品${to.params.id}`)
      next()
    }

我们按照顺序点击父组件的按钮 btn1 btn2 btn1 看下浏览器控制台

《对vue-router 3个钩子的理解》

很显然可以看到,当我点击btn1的时候,进入的是enter钩子,下面的btn2和btn1 都是使用的update钩子。

  • 问题2 你问题2的意思应该是这样: 我不使用path来传递参数而是使用name来传递参数。

答案结果是不可以。 至于为什么看下下面的解释。
当使用name来传递参数的时候,我们router index的配置如下:

    {
      path: '/parent',
      name: 'parent',
      component: Parent,
      children: [
        {
          path: 'child',
          name: 'child',
          component: Child,
        }
      ]
    },

父组件push方法:

        this.$router.push({
          name: 'child',
          params: {
            id: id
          }
        })

子组件不变

同样的我们点击btn1 、btn2 、btn1 发现控制台显示

《对vue-router 3个钩子的理解》

这样的结果意味着 我们只有第一次的enter钩子被触发了,下面的update钩子并没有被触发。

我的理解是这样的:如果使用name+prams来传递参数的话,我们可以看到url的路径其实是没有变化的。那么vue-router会复用上的parent和child组件。所以没办法看到参数的变化。

但是如果使用了path的话,由于url变化了,所以我们可以在child中使用钩子获取到参数的变化。

    原文作者:腹中有书气自华
    原文地址: https://segmentfault.com/a/1190000012726956
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞