程序化的事件侦听器

点击打开视频讲解更详细

现在,你已经知道了 $emit 的用法,它可以被 v-on 侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法。我们可以:

  • 通过 $on(eventName, eventHandler) 侦听一个事件
  • 通过 $once(eventName, eventHandler) 一次性侦听一个事件
  • 通过 $off(eventName, eventHandler) 停止侦听一个事件

你通常不会用到这些,但是当你需要在一个组件实例上手动侦听事件时,它们是派得上用场的。它们也可以用于代码组织工具。例如,你可能经常看到这种集成一个第三方库的模式:

// 一次性将这个日期选择器附加到一个输入框上
// 它会被挂载到 DOM 上。
mounted: function () {
// Pikaday 是一个第三方日期选择器的库
this.picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'
})
},
// 在组件被销毁之前,
// 也销毁这个日期选择器。
beforeDestroy: function () {
this.picker.destroy()
}

这里有两个潜在的问题:

  • 它需要在这个组件实例中保存这个 picker,如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。
  • 我们的建立代码独立于我们的清理代码,这使得我们比较难于程序化地清理我们建立的所有东西。

你应该通过一个程序化的侦听器解决这两个问题:

mounted: function () {
var picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'
}) this.$once('hook:beforeDestroy', function () {
picker.destroy()
})
}

使用了这个策略,我甚至可以让多个输入框元素同时使用不同的 Pikaday,每个新的实例都程序化地在后期清理它自己:

mounted: function () {
this.attachDatepicker('startDateInput')
this.attachDatepicker('endDateInput')
},
methods: {
attachDatepicker: function (refName) {
var picker = new Pikaday({
field: this.$refs[refName],
format: 'YYYY-MM-DD'
}) this.$once('hook:beforeDestroy', function () {
picker.destroy()
})
}
}

注意,即便如此,如果你发现自己不得不在单个组件里做很多建立和清理的工作,最好的方式通常还是创建更多的模块化组件。在这个例子中,我们推荐创建一个可复用的 组件。

完整案例:

<template>
<div id="app">
<!-- 比如,在页面挂载时定义计时器,需要在页面销毁时清除定时器。这看起来没什么问题。但仔细一看 this.timer
唯一的作用只是为了能够在beforeDestroy 内取到计时器序号,除此之外没有任何用处。 -->
</div>
</template> <script>
export default {
name: 'App',
data(){
return {
timer:''
}
},
mounted() {
// this.timer
// 如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。
// 我们可以通过 $on 或 $once 监听页面生命周期销毁来解决这个问题 // this.timer = setInterval(() => {
// console.log(Date.now())
// }, 1000) this.creatInterval('hello') //在mounted中创建多个生命周期函数。
this.creatInterval('world') //即使我们同时创建多个计时器,也不影响效果。因为它们会在页面销毁后程序化的自主清除。 },
// beforeDestroy() {
// clearInterval(this.timer)
// },
methods:{
creatInterval(msg) {
let timer = setInterval(() => {
console.log(msg)
}, 1000)
this.$once('hook:beforeDestroy', function() {
clearInterval(timer)
})
}
}
}
</script> <style scoped> </style>

052_末晨曦Vue技术_处理边界情况之程序化的事件侦听器的更多相关文章

  1. 048_末晨曦Vue技术_处理边界情况之使用$root访问根实例

    处理边界情况之使用$root访问根实例 点击打开视频教程 在每个 new Vue 实例的子组件中,其根实例可以通过 $root property 进行访问. 例如,在这个根实例中: src\main. ...

  2. 056_末晨曦Vue技术_处理边界情况之X-template

    处理边界情况之X-template 点击打开视频讲解更加详细 另一个定义模板的方式是在一个<script>元素中,并为其带上 text/x-template 的类型,然后通过一个 id 将 ...

  3. 051_末晨曦Vue技术_处理边界情况之provide和inject依赖注入

    provide和inject依赖注入 点击打开视频讲解更详细 在此之前,在我们描述访问父级组件实例的时候,展示过一个类似这样的例子: <google-map> <google-map ...

  4. 057_末晨曦Vue技术_处理边界情况之强制更新($forceUpdate)与通过 v-once 创建低开销的静态组件

    强制更新($forceUpdate) 点击打开视频讲解更加详细 在vue中,如果data中有基本数据类型变量:age,修改他,页面会自动更新. 但如果data中的变量为数组或对象(引用数据类型),我们 ...

  5. 054_末晨曦Vue技术_处理边界情况之组件之间的循环引用

    组件之间的循环引用 点击打开视频讲解更详细 假设你需要构建一个文件目录树,像访达或资源管理器那样的.你可能有一个 <tree-folder> 组件,模板是这样的: <p> &l ...

  6. 057_末晨曦Vue技术_处理边界情况之强制更新和创建低开销的静态组件

    强制更新和创建低开销的静态组件 点击打开视频讲解更加详细 强制更新 如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事. 你可能还没有留意到数组或对象的变更检 ...

  7. 066_末晨曦Vue技术_过渡 & 动画之多个元素的过渡

    多个元素的过渡 点击打开视频讲解更加详细 我们之后讨论多个组件的过渡,对于原生标签可以使用 v-if/v-else.最常见的多标签过渡是一个列表和描述这个列表为空消息的元素: <transiti ...

  8. 058_末晨曦Vue技术_过渡 & 动画之过渡的类名

    进入/离开 & 列表过渡 点击打开视频讲解更加详细 概述 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.包括以下工具: 在 CSS 过渡和动画中自动应用 class ...

  9. Vue学习计划基础笔记(二) - 模板语法,计算属性,侦听器

    模板语法.计算属性和侦听器 目标: 1.熟练使用vue的模板语法 2.理解计算属性与侦听器的用法以及应用场景 1. 模板语法 <div id="app"> <!- ...

随机推荐

  1. Kubernetes client-go Informer 源码分析

    概述ControllerController 的初始化Controller 的启动processLoopHandleDeltas()SharedIndexInformersharedIndexerIn ...

  2. MySQL - 分页问题

    MySQL中的分页 MySQL中通过LIMIT关键字可以实现分页,如:(其中0表示开始记录数,10表示返回数据的数量) SELETE * FROM table_name LIMIT 0, 10 MyB ...

  3. 接口测试postman深度挖掘应用①

    一.测试接口前需要搞明白的原理: 1.在讲如何使用postman时,我们首先应该要了解网络的请求相应的知识,下面以fiddle进行抓包为例分析: 通过fiddler抓包我们不难发现,客户端也就是用户会 ...

  4. 2021.06.12【NOIP提高B组】模拟 总结

    T1 题目大意:有 \(n\) 个点,到点 \(i\) 可以获得 \(A_i\) ,同时消耗 \(B_i\) 若当前价值小于 \(B_i\) 则不能到,问从 \(P\) 开始,任一点结束后的最大值. ...

  5. ABP Framework 5.3.0 版本新增功能和变更说明

    ABP Framework 5.3.0 稳定版已在2022年6月14日正式发布. 以下是本版本的新增功能: "开始"页面提供创建单层项目选项 启动模板提供 PWA 支持 Volo. ...

  6. 记安装AWVS14过程踩的坑

    由于之前的AWVS14用着用着无法扫描了,一扫就是失败,一气之下就重装系统了.重装系统后发现安装还是不行,折腾了好久,终于找到方法了. 安装acunetix_14.1.210324124.exe 没啥 ...

  7. 关于个人项目(臻美MV【仿抖音App】)滑动切换视频的分析(前端角度)

    我们知道你天天刷抖音的时候可以上滑切换视频,互不影响.那么我们站在前端的角度能否可以实现这种效果呢?这是我的个人项目:臻美MV 下面我是用Vue写的,现在我把它开源. Vue: 初始界面 <te ...

  8. UiPath条件判断活动If的介绍和使用

    if的介绍 if语句是指编程语言(包括c语言.C#.Python.Java.汇编语言等)中用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一. if在UiPath中的使用 ...

  9. 原生实现.NET5.0+ 自定义日志

    一.定义一个静态类 声明一个 ReaderWriterLockSlim 对象 用于并发控制 1 /// <summary> 2 /// IO锁 3 /// </summary> ...

  10. Leetcode 不同路径系列

    Leetcode不同路径系列题解笔记 62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 "Start" ). 机器人每次只能向下或者向右移动一 ...