验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

vue2中的@hook怎么使用

阅读:546 来源:乙速云 作者:代码code

vue2中的@hook怎么使用

      前言

      @hook是什么?用来监听组件生命周期的回调函数。

      这和生命周期函数mounted,created,updated有什么区别?

      区别1:@hook 会在对应的生命周期函数执行后执行。

      区别2:@hook 可以在父组件监听子组件的生命周期运行情况。

      vue2中的@hook怎么使用

      从这段vue源代码中我们能看到hook的部分调用逻辑,vm.$emit('hook:' + hook) 其实就是在调用我们写的@hook:mounted="xxx",@hook这个api却没有在官方文档中出现,所以鲜有人知道它的存在和用法。

      几种用法

      用法一 将放在多个生命周期的逻辑,统一到一个生命周期中

      通常写法

      export default {
        components: {},
        data: () => {
          return {
            name: 'dx',
          };
        },
        created() {
          console.log('created')
        },
        beforeMount() {
          console.log('beforeMount')
        },
        mounted() {
          console.log(this.name);
          // 每一个小时刷新一次页面
          setInterval(() => {
            location.reload()
          }, 60 * 60 * 1000);
        },
      }

      @hook的用法

      export default {
        components: {},
        data: () => {
          return {
            name: 'dx',
          };
        },
        created() {
          console.log('created');
          this.$on('hook:beforeMount', () => {
            console.log('beforeMount');
          });
          this.$on('hook:mounted', () => {
            console.log(this.name); // this 就是组件实例自己
            // 每一个小时刷新一次页面
            setInterval(() => {
              location.reload();
            }, 60 * 60 * 1000);
          });
        },
      };

      注意

      1. 按照生命周期执行的先后周期,我们只能mounted生命周期里,写这之后的生命周期,而不能写hook:beforeMount

      2. this.$on第二个回调函数的this指的是当前组件实例本身,无论这个回调函数是否是箭头函数。

      用法二 监听子组件生命周期运行的情况

      通常写法

      // 父组件
      
      
      export default {
        name: 'Parents',
        components: {
        	Children
        },
        data: () => {
          return {
            name: 'dx',
          };
        },
        methods: {
          ButtonRender() {
            console.log('渲染完成')
          }
        }
      }
      // 子组件
      export default {
        name: 'Children',
        components: {},
        data: () => {},
        methods: {},
        mounted() {
        	this.$emit('buttonRender')
        }
      }

      @hook的写法

      
      
      export default {
        name: 'Parents',
        components: {
        	Children
        },
        data: () => {
          return {
            name: 'dx',
          };
        },
        methods: {
          ButtonRender() {
            console.log('渲染完成')
          }
        }
      }

      注意

      1. @hook的写法可以不需要在子组件里面编写其它代码

      2. 从vue源码中可以发现 vm.$emit('hook:' + hook) 这里虽然调用了hook但没有返回参数,也就是说,上面代码中ButtonRender没有默认参数。

      3. 同样承接着2来说,由于ButtonRender没有默认参数,所以我们无法在ButtonRender函数中获取子组件Children的实例。

      为了解决3的问题,我尝试着想到一种方法,利用ref获取子组件的实例,将子组件的实例拿到父组件的this中。ButtonRender中的this就是父组件实例,和寻常methods中的函数没区别。

      
      export default {
        name: 'Parents',
        components: {
        	Children
        },
        data: () => {
          return {
            name: 'dx'
          };
        },
        mounted() {},
        methods: {
          ButtonRender() {
            console.log(this.$refs.child1) // this.$refs.child1就是子组件Children的实例了
            console.log('渲染完成')
          }
        }
      };

      但是,我们都知道,vue ref的绑定都是挂载完成之后,所以这个方法也只能用在@hook:mounted@hook:updated等mounted之后执行的生命周期中,而不能用在 比如@hook:beforeMount中。

      运用场景

      场景一

      许多时候,我们不得不在不同的生命周期中执行某些逻辑,并且这些逻辑会用到一些通用的变量,这些通用变量按照之前的方式,我们不得不存在data中。

      优化后,就不存在这个问题,是不是很好用。

      场景二

      如果属于同一业务的逻辑要在不同的生命周期中执行,下面这样会更利于阅读和维护。

      export default {
        created() {
          this.$on('hook:mounted', () => {
            挂载时执行一些业务A相关逻辑
          })
          this.$on('hook:updated', () => {
            挂载时执行一些业务A相关逻辑
          })
          this.$once('hook:beforeDestroy', () => {
            挂载时执行一些业务A相关逻辑
          })
        }
      }

      场景三

      想要监听别人封装好的组件(第三方组件)的生命周期,你不可能去第三方子组件的生命周期中写代码。

      比如 element-ui 的button组件,在子组件渲染完成后,我想做某些逻辑变更。

      {{name}}
      
      export default {
        name: 'Parents',
        data: () => {
          return {
            name: 'dx',
            disabled: true
          };
        },
        methods: {
          ButtonRender() {
            this.disabled = false
            this.name = 'yx'
          }
        }
      }

      所有生命周期执行的顺序

      第一次渲染

      父beforeCreate
      父 hook:beforeCreate
      父created
      父 hook:created
      父beforeMount
      父 hook:beforeMount
      子beforeCreate
      子hook:beforeCreate
      子created
      子hook:created
      子beforeMount
      子hook:beforeMount
      子mounted
      子hook:mounted
      父mounted
      父 hook:mounted

      更新时

      父beforeUpdate
      父hook:beforeUpdate
      子beforeUpdate
      子hook:beforeUpdate
      子updated
      子hook:updated
      父updated
      父hook:updated

      组件摧毁时

      父beforeDestroy
      父hook:beforeDestroy
      子beforeDestroy
      子hook:beforeDestroy
      子destroyed
      子hook:destroyed
      父destroyed
      父hook:destroyed

      以上内容涉及到vue父子组件生命周期执行顺序的知识,但对于@hook:xxx来说,在xxx执行后就会立即执行@hook:xxx

    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>