程序化的事件侦听器

点击打开视频讲解更详细

现在,你已经知道了 $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. isprime

    C++实现求素数个数 问题描述 求1~n的素数个数(例:n=10) 1 2 3 4 5 6 7 8 9 10 prime 2 3 5 7 not prime 1 4 6 8 9 10 素数又称质数.所 ...

  2. 逻辑运算符——JavaSE基础

    逻辑运算符 运算符 说明 逻辑与 &( 与) 两个操作数为true,结果才是true,否则是false 逻辑或 |(或) 两个操作数有一个是true,结果就是true 短路与 &&am ...

  3. CF908D New Year and Arbitrary Arrangement 题解

    \(0.\) 前言 有一天 \(Au\) 爷讲期望都见到了此题,通过写题解来加深理解. \(1.\) 题意 将初始为空的序列的末尾给定概率添加 \(a\) 或 \(b\),当至少有 \(k\) 对 \ ...

  4. Solon 1.8.3 发布,云原生微服务开发框架

    相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...

  5. Python基础学习笔记_01

    Python的介绍 1989年圣诞节创造,1991年正真出生,目前更新到3.0版本 具有最庞大的"代码库",人称"胶水语言",无所不能 一种跨平台的计算机程序设 ...

  6. mybatis查询mysql 数据库中 BLOB字段,结果出现乱码

    起因 mybatis-plus 通过Mapper 查询数据,映射出来的BLOB字段中的yml数据中文是乱码的 --- DefaultValue: '' Formula: '' HintContent: ...

  7. mysql备份数据库linux

    备份数据库 问题描述: ​ 我们用的是mysql,以今天遇到的情况为例,我们是在两台服务器上要搭相同的平台,部署完成后页面报错,发现是数据库的问题,我们打开数据库查看,确实数据库中少建一个wind数据 ...

  8. Turtle绘图——python简单上手小案例

    Turtle绘图 Turtle模块提供了在二维平面上移动的环境. Turtle可以实现位置.航向和各种可能的状态和动作. import turtle as tu roo = tu.Turtle() # ...

  9. 最著名的著名的比特币BTC钱包地址-中本聪的钱包

    最著名的著名的比特币BTC钱包地址-中本聪的钱包1.比特币创始人中本聪 1PTFYUG6nCzRrByoRfGT5kefUNuZjNF84o这个地址还是比特币的创世地址,比特币从未移动过,其中的50币 ...

  10. Entry键值对对象和Map集合遍历键值对方式

    我们已经知道,Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在IMap 中是一一对应关系, 这一对对象又称做Map 中的一个Entry(项).Entry将键值对的对应 ...