定时器

看到过一个 Vue 开发技巧,讲的是关于处理组件内定时器的步骤。

通常我们一般都是这样操作的:

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

但是其实更好的做法是:

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

vm.$once( event, callback )
参数:

  • {string} event
  • {Function} callback
用法:监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。

语法

从语法上来看,就是组件内的生命周期函数在执行结束后会 $emit 一个"hook + 生命周期名字" 的自定义事件。

子组件内部监听

这样的话,我们就可以在一个生命周期方法里监听其余生命周期的发生(如上例所示)。

一些情况下确实可以达到优化或简化代码的效果。比如处理组件内多个生命周期的逻辑变得非常简单,简单到只有一句时,这个时候就可以考虑将这些代码放在 created 或者 mounted 里通过这种方式来监听并执行那些简单逻辑。

父组件对子组件监听

当组件内的生命周期函数在执行结束后 $emit 的自定义事件。不仅仅可以在组件内被 $on。vue 的语法决定了这些事件也可以被父组件 v-on 到。

设想一个需求场景:

一个页面里需要加载一个可视化组件,这个组件里面的逻辑极其复杂,存在大量复杂的计算。因为考虑可能要在多个地方使用,就并没有引入主题相关的 loading。我们的需求是什么呢?

就是在数据渲染到页面的之前让页面 loading。mounted 之后停止 loading。beforeUpdata 时开始 loading。updatad 之后停止 loading。

最简单的方法就是改写组件的生命周期函数,使其在 mounted/beforeUpdata/updatad 时通知父组件显示或者隐藏 loading。

这样做显然不好,因为侵入了子组件的逻辑,增加的逻辑也和组件本身的功能好不关联。最好的办法就是使用 v-on=“hook:xxx” 的方式:

<v-chart
    @hook:mounted="loading = false"
    @hook:beforeUpdated="loading = true"
    @hook:updated="loading = false"
    :data="data"
/>

这样,就实现了对子组件生命周期的监听。对任意的组件都有效果,包括引入的第三方组件。

Logo

前往低代码交流专区

更多推荐