Vue 中 $on $once $off $emit 详细分析,以及使用
vue的 $on,$emit,$off,$once
Api 中的解释:
$on(eventName:string|Array, callback) 监听事件
- 监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
$once(eventName: string, callback) 监听事件
- 监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。
$off(eventName: string| Array, callback) 移除自定义事件监听器
1. 如果没有提供参数,则移除所有的事件监听器; 2. 如果只提供了事件,则移除该事件所有的监听器; 3. 如果同时提供了事件与回调,则只移除这个回调的监听器。
使用 $emit(eventName, [..args]) 触发事件
- 触发当前实例上的事件。附加参数都会传给监听器回调
$on 实现原理
Vue.prototype.$on = function (event, fn) {
var vm = this;
if (Array.isArray(event)) {
for (var i = 0, l = event.length; i < l; i++) {
vm.$on(event[i], fn);
}
} else {
(vm._events[event] || (vm._events[event] = [])).push(fn);
// optimize hook:event cost by using a boolean flag marked at registration
// instead of a hash lookup
if (hookRE.test(event)) {
vm._hasHookEvent = true;
}
}
return vm
};
$once 实现原理
Vue.prototype.$once = function (event, fn) {
var vm = this;
function on () {
vm.$off(event, on);
fn.apply(vm, arguments);
}
on.fn = fn;
vm.$on(event, on);
return vm
};
$off
Vue.prototype.$off = function (event, fn) {
var vm = this;
// all
if (!arguments.length) {
vm._events = Object.create(null);
return vm
}
// array of events
if (Array.isArray(event)) {
for (var i$1 = 0, l = event.length; i$1 < l; i$1++) {
vm.$off(event[i$1], fn);
}
return vm
}
// specific event
var cbs = vm._events[event];
if (!cbs) {
return vm
}
if (!fn) {
vm._events[event] = null;
return vm
}
// specific handler
var cb;
var i = cbs.length;
while (i--) {
cb = cbs[i];
if (cb === fn || cb.fn === fn) {
cbs.splice(i, 1);
break
}
}
return vm
};
$emit 实现原理
Vue.prototype.$emit = function (event) {
var vm = this;
{
var lowerCaseEvent = event.toLowerCase();
if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
tip(
"Event \"" + lowerCaseEvent + "\" is emitted in component " +
(formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " +
"Note that HTML attributes are case-insensitive and you cannot use " +
"v-on to listen to camelCase events when using in-DOM templates. " +
"You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"."
);
}
}
var cbs = vm._events[event];
if (cbs) {
cbs = cbs.length > 1 ? toArray(cbs) : cbs;
var args = toArray(arguments, 1);
var info = "event handler for \"" + event + "\"";
for (var i = 0, l = cbs.length; i < l; i++) {
invokeWithErrorHandling(cbs[i], vm, args, vm, info);
}
}
return vm
};
用法:监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
应用
- 多次绑定,$on, $once 将多次调用,$off 调用一次将解绑所有相同名字的$on, $once 监听事件
<template>
<div class="hello">
<button @click="onEmit">OnEmit</button>
<button @click="onOff">OnOff</button>
<button @click="onOn">on</button>
</div>
</template>
<script>
export default {
name: 'Test',
mounted() {
},
methods: {
onEmit() {
this.$emit('onTest', 1);
this.$emit('onTest', 2)
this.$emit('onTest', 3)
this.$emit('onTest', 4)
this.$emit('onTestOnce', 5);
this.$emit('onTestOnce', 6);
this.$emit('onTestOnce', 7);
this.$emit('onTestOnce', 8);
},
onOff() {
this.$off('onTest');
},
onOn(){
this.$on('onTest', (args) => {
console.log(args)
})
this.$once('onTestOnce', (args) => {
console.log(args)
})
}
}
}
</script>
子组件到父组件通讯
<hello @pfn="parentFn"></hello>
<script>
Vue.component('hello', {
template: '<button @click="fn">按钮</button>',
methods: {
// 子组件:通过$emit调用
fn() {
this.$emit('pfn', '这是子组件传递给父组件的数据')
}
}
})
new Vue({
methods: {
// 父组件:提供方法
parentFn(data) {
console.log('父组件:', data)
}
}
})
</script>
非父子组件通讯
- 组件 A.vue
<template>
<div @click="onAon">
组件a
</div>
</template>
<script>
// import bus from "@/components/bus";
export default {
name: 'A',
methods: {
onAon() {
this.$bus.$emit('bTest')
}
}
}
</script>
组件B.vue
<template>
<div>
b 组件
</div>
</template>
<script>
// import bus from "@/components/bus";
export default {
mounted() {
this.$bus.$on('bTest', () => {
console.log('---- 触发b组件监听 ------')
})
}
}
</script>
- bus.js
import Vue from "vue";
let bus = new Vue();
export default bus;
注:可以将bus 全局引入
Vue 中 $on $once $off $emit 详细分析,以及使用的更多相关文章
- ZIP压缩算法详细分析及解压实例解释
最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...
- 1125MySQL Sending data导致查询很慢的问题详细分析
-- 问题1 tablename使用主键索引反而比idx_ref_id慢的原因EXPLAIN SELECT SQL_NO_CACHE COUNT(id) FROM dbname.tbname FORC ...
- LinkedList详细分析
一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...
- android ListView 九大重要属性详细分析、
android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...
- C语言中的static 详细分析
转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...
- Linux内核OOM机制的详细分析(转)
Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...
- Android-Native-Server 启动和注册详细分析
Android-Native-Server 启动和注册详细分析 以mediaService为实例来讲解: mediaService的启动入口 是一个 传统的 main()函数 源码位置E:\ ...
- px,dp,dip,sp,in,mm,pt详细分析
px,dp,dip,sp,in,mm,pt详细分析 px :(pixels),屏幕的像素点,不同的设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多. dip :(devi ...
- Http Pipeline详细分析(下)
Http Pipeline详细分析(下) 文章内容 接上面的章节,我们这篇要讲解的是Pipeline是执行的各种事件,我们知道,在自定义的HttpModule的Init方法里,我们可以添加自己的事件, ...
随机推荐
- 4.19——数组双指针——26. 删除有序数组中的重复项 & 27. 删除有序数组中的重复项II & 80. 删除有序数组中的重复项 II
第一次做到数组双指针的题目是80: 因为python的List是可以用以下代码来删除元素的: del List[index] 所以当时的我直接用了暴力删除第三个重复元素的做法,大概代码如下: n = ...
- Python设置Excel样式
前面已经详细讲解过使用Python对Excel表格进行读.写操作,本文主要讲解下使用Python设置Excel表格的样式. 深入学习请参考openpyxl官方文档: https://openpyxl. ...
- 【UE4 C++】UKismetSystemLibrary 源代码
// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" # ...
- [对对子队]会议记录5.22(Scrum Meeting9)
今天已完成的工作 梁河览 工作内容:修改第一到九关新手引导,修复关卡选择bug 相关issue:优化初步导出版本 相关签入:fix:修改第一关到第九关的新手引导和地图场景的bug 马嘉 ...
- 大牛针对零基础入门c语言详解指针(超详细)
C语言指针说难不难但是说容易又是最容易出错的地方,因此不管是你要做什么只要用到C指针你就跳不过,今天咱们就以 十九个例子来给大家简单的分析一下指针的应用,最后会有C语言视频资料提供给大家更加深入的参考 ...
- Java中的位运算符 &、|、^、~、<< 和 >>
一.& 按位与运算符 5 & 3 = 1 5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101 3转换为二进制:0000 0000 0000 ...
- 链表中倒数第K个结点 牛客网 剑指Offer
链表中倒数第K个结点 牛客网 剑指Offer 题目描述 输入一个链表,输出该链表中倒数第k个结点. # class ListNode: # def __init__(self, x): # self. ...
- simulate_screencap
#!/bin/bashadb shell screencap -p /sdcard/screen.pngadb pull /sdcard/screen.png ./adb shell rm /sdca ...
- 虚拟机克隆后修改mac地址和ip地址
(1)虚拟机克隆在新的虚拟机下会有文件产生变化. /etc/udev/rules.d/70-persistent-net.rules 文件中会多一个eth1 网卡的文件 ,eth0 的那行文件是原虚 ...
- oracle 数据库修改端口号1521
1.关闭监听 2.修改配置文件,port=1933 #vi $ORACLE_HOME/network/admin/listener.ora 3.登录并查看local_listener参数,因为使用的是 ...