vue2中@hook的解析与妙用实例

 更新时间:2023年03月06日 11:06:49   作者:可缺不可滥  
vue-hooks是简化组件定义、复用状态逻辑的一种最新尝试,下面这篇文章主要给大家介绍了关于vue2中@hook的解析与妙用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

前言

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

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

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

区别2:@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指的是当前组件实例本身,无论这个回调函数是否是箭头函数。

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

通常写法

// 父组件
<Children @buttonRender="ButtonRender"/>

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的写法

<Children @hook:mounted="ButtonRender"/>

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中的函数没区别。

<Children ref="child1" @hook:mounted="ButtonRender"/>
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中。

<script>
export default {
  data() {
    return {
        timer:null
      }
  }
  mounted () {
    this.timer = setInterval(() => {
	// todo
    }, 1000);
  }
  beforeDestroy () {
    clearInterval(this.timer)
  }
}
</script>

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

<script>
export default {
  mounted () {
    const timer = setInterval(() => {
	// todo
    }, 1000);
    this.$once('hook:beforeDestroy', function () {
        clearInterval(timer)
    })
  }
}
</script>

场景二

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

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

场景三

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

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

<el-button type="primary" @hook:mounted="ButtonRender" :disabled="disabled">{{name}}</el-button>

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

总结

到此这篇关于vue2中@hook的解析与妙用的文章就介绍到这了,更多相关vue2 @hook妙用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 想到头秃也想不到的Vue3复用组件还可以这么hack的用法

    想到头秃也想不到的Vue3复用组件还可以这么hack的用法

    这篇文章主要为大家介绍了想到头秃也想不到的Vue3复用组件还可以这么hack的用法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • vue2.x 通过后端接口代理,获取qq音乐api的数据示例

    vue2.x 通过后端接口代理,获取qq音乐api的数据示例

    今天小编就为大家分享一篇vue2.x 通过后端接口代理,获取qq音乐api的数据示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10
  • vue+quasar使用递归实现动态多级菜单

    vue+quasar使用递归实现动态多级菜单

    这篇文章主要为大家详细介绍了vue+quasar使用递归实现动态多级菜单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 浅析Vue中拆分视图层代码的5点建议

    浅析Vue中拆分视图层代码的5点建议

    这篇文章主要介绍了Vue中拆分视图层代码的5点建议,下面就如何进行脚本代码拆分提供一些思路,有一些可能是很基本的原则,为尽可能完整就放在一起,你并不需要从最开始就采纳所有的建议。需要的朋友可以参考下
    2019-08-08
  • vue2.0使用md-edit编辑器的过程

    vue2.0使用md-edit编辑器的过程

    这篇文章主要介绍了vue2.0+使用md-edit编辑器的解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-02-02
  • vue.js template模板的使用(仿饿了么布局)

    vue.js template模板的使用(仿饿了么布局)

    这篇文章主要介绍了vue.js template模板的使用,主要是模仿饿了么布局,用到了4个组件,分别是header.vue,goods.vue,ratings.vue,seller.vue,感兴趣的朋友跟随脚本之家小编一起看看实现代码
    2018-08-08
  • vue进入页面时滚动条始终在底部代码实例

    vue进入页面时滚动条始终在底部代码实例

    这篇文章主要介绍了vue进入页面时滚动条始终在底部,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Vue进度条progressbar组件功能

    Vue进度条progressbar组件功能

    progressbar组件在一个可以直接运行的npm包,通过Yeoman进行构建,再通过Gulp+Webpack构建工具。这篇文章给大家介绍了Vue进度条progressbar组件
    2018-04-04
  • vue实现静态页面点赞和取消点赞功能

    vue实现静态页面点赞和取消点赞功能

    这篇文章主要为大家详细介绍了vue实现静态页面点赞和取消点赞的功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • vue实现购物车案例

    vue实现购物车案例

    这篇文章主要为大家详细介绍了vue实现购物车案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论