vue中可以绑定多个事件吗

目录
  • vue可以绑定多个事件吗
    • 第一种
    • 第二种
  • vue事件绑定的原理
    • 1.1 原生 dom 的绑定
    • 1.2 组件中绑定事件
    • 1.3 $on 是怎么实现的

vue可以绑定多个事件吗

标签绑定一个事件处理函数,然后在相应的事件处理函数中调用想要触发的多个处理函数

以下两种方案,都可以实施

第一种

<button id="test" @click="test1">按钮</button>
new Vue({
    el:"#test",
    data:"",
    methods:{
        test1:function(){
            alert("test1");
            this.test2();
            this.test3();
        },
        test2:function(){
            alert("test2");
        },
        test3:function(){
            alert("test3");
        }
    }
})

第二种

绑定多个事件时,事件之间使用分号“;”分开即可

<el-button type="primary" size="small" @click="add1();add2();">123</el-button>

去methods中添加事件的函数

methods:{
    add1(){
        console.log(123)
    },
    add2(){
        console.log(456)
    },
    }

vue事件绑定的原理

之前我搜这个原理的时候,好多文章,都只写了两句话:

  • 原生事件绑定是通过addEventListener绑定给真实元素的。
  • 组件事件绑定是通过Vue自定义的key$on实现的。

那具体是怎么实现的呢, 没有说?

就现在具体看一下。

// 原生事件绑定
<div @click="fn()"></div>
// 组件绑定
<my-component @click.native="fn" @click="fn1"></my- component>

原理:

事件的编译:

let compiler = require('vue-template-compiler'); //vue-loader
let r1 = compiler.compile('<div @click="fn()"></div>');
let r2 = compiler.compile('<my-component @click.native="fn" @click="fn1"></my- component>'); console.log(r1);
// {on:{click}} console.log(r2);
// {nativeOn:{click},on:{click}}

两者编译出来不一样

// 前者
with (this){return _c('div',{on:{"click":function($event){return fn()}}})}
// 后者
with (this){return _c('my-component',{on:{"click":fn1},nativeOn:{"click":function($event){return fn($event)}}})}

1.1 原生 dom 的绑定

  • Vue 在创建真是 dom 时会调用 createElm ,默认会调用 invokeCreateHooks
  • 会遍历当前平台下相对的属性处理代码,其中就有 updateDOMListeners 方法,内部会传入 add 方法

源码:

function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) {
	if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) { return }
	const on = vnode.data.on || {} const oldOn = oldVnode.data.on || {}
	target = vnode.elm
	normalizeEvents(on)
	updateListeners(on, oldOn, add, remove, createOnceHandler, vnode.context)
	target = undefined
}
function add (
	name: string,
	handler: Function,
	capture: boolean,
	passive: boolean
) {
	target.addEventListener( // 给当前的dom添加事件
		name,
		handler,
		supportsPassive
		? {  capture, passive  }
		: capture
	)
}

1.2 组件中绑定事件

export function updateComponentListeners (
	vm: Component,
	listeners: Object,
	oldListeners: ?Object
) {
	target = vm updateListeners(
		listeners, oldListeners || {},
		add,
		remove,
		createOnceHandler, vm)
		target = undefined
}
function add (event, fn) {
	target.$on(event, fn)
}

组件绑定事件是通过 vue 中自定义的 $on 方法来实现的

1.3 $on 是怎么实现的

vm.$on( event, callback )

作用:

监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。

原理:

$on是采用了经典的发布订阅者设计模式,首先定义一个事件中心,通过$on订阅事件,将事件存储在事件中心里面,然后通过$emit触发事件中心里面存储的订阅事件。

Vue.prototype.$on = function (event, fn) {
    const vm: Component = this
    if (Array.isArray(event)) {
        for (let i = 0, l = event.length; i < l; i++) {
            this.$on(event[i], fn)
        }
    } else {
        (vm._events[event] || (vm._events[event] = [])).push(fn)
    }
    return vm
}

看代码,逻辑很简单,$on函数接收俩个参数,第一个是订阅的事件名,可以是多个,如果是多个就传入一个事件名数组。另一个是回调函数。

首先判断传入的事件是不是一个数组,如果是,那么遍历这个数组,将数组中的每一个事件都递归调用$on方法将其作为单个事件订阅。

如过不是数组,那就当做单个事件名来处理,以该事件名作为key,先尝试在当前实例的_events属性中获取其对应的事件列表,如果获取不到就给其赋空数组为默认值,并将第二个参数回调函数添加进去。

多说一句,实例的_events是什么?这就是在事件初始化的时候,initEvents函数中绑定了_event属性并给其赋值为空对象。这个_events属性就是用来作为当前实例的事件中心,所有绑定在这个实例上的事件都会存储在事件中心_events属性中。

这就是$on的内部原理。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue快速理解事件绑定是什么

    目录 一.监听事件 二.事件修饰符 1.stop修饰符阻止事件冒泡 2.capture修饰符 3.self修饰符 4.prevent修饰符 5.键盘事件修饰符 6.鼠标事件修饰符 一.监听事件 监听事件一般使用的是v-on指令,可以在JavaScript代码中将v-on直接将写在代码上面,语法是:v-on:你所定的事件名=‘代码’,v-on指令可以接收到函数的调用,并且将其分成是无参数调用函数还是有参数调用函数.当然v-on函数可以简写成@+事件名的写法,很方便. 在初始化vue对象的时候要申明

  • Vue2 模版指令元素绑定事件执行顺序解析

    目录 Vue 自定义指令的执行机制 前情提要 DOM绑定 源码 directive 为什么先调用模版绑定的方法,再调用指令的方法 总结 Vue 自定义指令的执行机制 version: 2.6.14 前情提要 某日,业务需要我需要在按钮点击之前验证某些条件,如果不符合即不执行click内的业务代码.思前想后,写一个指令不就可以了.做到既不改动原有的业务代码,又可以移植. <template> <button v-capture @click="handleClick"&

  • vue如何给自定义的组件绑定点击事件

    目录 给自定义的组件绑定点击事件 给自定义组件添加单击事件 给自定义的组件绑定点击事件 在做项目中我们往往会封装许多的组件,来减少代码的重复性,提高代码的可利用性,有时候也会给组件绑定事件,但是经常会失效. 先给cardinfo这个组件绑定一个点击事件      <cardinfo         :content="content"         :from="from"         :ProPortrait="ProPortrait&quo

  • vue中@click绑定事件点击不生效的解决

    目录 @click绑定事件点击不生效 原因 解决方法 @click中不能使用三则表达式原因 @click绑定事件点击不生效 原因 根据Vue2.0官方文档关于父子组件通讯的原则,父组件通过prop传递数据给子组件,子组件触发事件给父组件.但父组件想在子组件上监听自己的click的话,需要加上native修饰符. 解决方法 方法1:在@click后加上.native(监听根元素的原生事件,使用 .native 修饰符) @click.native = "..." 方法2:向外发送clic

  • 详解Vue的数据及事件绑定和filter过滤器

    目录 Vue数据绑定 单向绑定 双向绑定 值绑定 事件绑定 事件处理器 事件修饰符 键值修饰符 class与style绑定 绑定class 绑定内联样式 filter过滤器 总结 Vue数据绑定 单向绑定 将Model绑定到View后,当用JavaScript代码更新Model时,View会自动更新.(模型——>视图) 单向绑定的实现过程是: 所有数据只保存一份. 一旦数据变化,就去更新页面(只有data——>DOM,没有DOM——>data) 若用户在页面上做了更新,就手动收集(双向绑

  • vue项目input标签checkbox,change和click绑定事件的区别说明

    目录 input标签checkbox,change和click绑定事件的区别 input标签中checkbox类型的相关操作总结 一.checked属性 二.操作 三.关于checkbox的其他操作 input标签checkbox,change和click绑定事件的区别 我们经常在vue开发项目的过程中,遇到需要对input框使用v-modal的这种情况,在有的时候,不光需要双向数据绑定,还需要在改变数据之后绑定其它的操作,那么问题来了,你是使用@change绑定事件还是使用@click绑定事件

  • Vue之表单事件数据绑定详解

    <body> <div id="root"> <form action="" @submit.prevent="demo"> <label for="TW"> 姓名:</label> <input type="text" id="TW" v-model.trim="userInfo.account"&g

  • 对vue中v-on绑定自定事件的实例讲解

    关于官网vue中v-on绑定自定义事件的个人理解 对官网实例进行了一些修改,如下图: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-on绑定自定义事件</title> <script src="vue.js"></script> </head>

  • vue中可以绑定多个事件吗

    目录 vue可以绑定多个事件吗 第一种 第二种 vue事件绑定的原理 1.1 原生 dom 的绑定 1.2 组件中绑定事件 1.3 $on 是怎么实现的 vue可以绑定多个事件吗 标签绑定一个事件处理函数,然后在相应的事件处理函数中调用想要触发的多个处理函数 以下两种方案,都可以实施 第一种 <button id="test" @click="test1">按钮</button> new Vue({     el:"#test&qu

  • 浅谈vue中组件绑定事件时是否加.native

    组件绑定事件时 1. 普通组件绑定事件不能添加.native, 添加后事件失效 2. 自定义组件绑定事件需要添加.native, 否则事件无效 <template> <!-- <mt-field label="用户名" placeholder="请输入用户名"></mt-field> --> <input type="text" @keyup.native="show($event)

  • 基于vue中对鼠标划过事件的处理方式详解

    鼠标事件进行监听 需求中,在一个table(组件)表中,对于其中一列(该列为图片列),当鼠标划过该列的某个单元格子(图片)时,需要展示出该单元格子对应的遮罩层 翻阅了一些博客,发现好多都提到了mouse事件,如mouseover.mouseout.mouseenter.mouseleave,在之后我自己也通过这种方法进行了尝试. <template> <el-table :data="tableData" stripe style="width: 100%&

  • vue中el-input绑定键盘按键(按键修饰符)

    vue怎么写键盘事件 vue允许将按键值作为修饰符来使用,如监听回车事件,有两种写法,如下代码: <input type="text" @keyup.13="console.log($event)"></input> <input type="text" @keyup.enter="console.log($event)"></input> 但要注意的是:当我们在在el-inpu

  • Vue中父子组件通信与事件触发的深入讲解

    目录 一.组件 子组件 父组件 二.父子组件通信 父组件给子组件通信 子组件向父组件通信 三.父子组件事件触发 父组件调用子组件中的事件方法 子组件调用父组件中的事件方法 四.总结 一.组件 子组件 <template> <div style="border:1px solid black;width:400px; height: 130px;"> <h3>我是子组件</h3> <button>子组件将值传递给父组件</

  • vue中使用element组件时事件想要传递其他参数的问题

    在使用element的上传组件时在一下几个钩子中传递其他参数 图中是文件上传时的几个钩子,参数为文件或文件列表或者其他参数,但是现在我想在原有参数上传递其他参数.比如我想在on-success的钩子中传递一个自定义参数i,原本是这样写的: :on-success="handleSuccess(i)" //handleSuccess是一个方法 但是发现这样写取不到自身原来的参数,后来在网上找到了一个比较好的方法,如下: :on-success="(value)=> han

  • vue中div禁止点击事件的实现

    目录 div禁止点击事件 div作为按钮不可点击问题的处理 div禁止点击事件 在props里面定义一个判断是不是只读的属性. 在最外面的div里面添加三元表达式 pointer-events: none;是禁止鼠标点击事件 div作为按钮不可点击问题的处理 vue中div作为按钮,使用:disabled="flag"(flag为布尔类型)控制按钮是否可点击,发现无论flag为true还是false,div按钮都可点击. 解决方法,将div换成button. 以上为个人经验,希望能给大

  • vue中对监听esc事件和退出全屏问题的解决方案

    目录 对监听esc事件和退出全屏问题的解决 下面是全屏的完整代码 element+vue全屏与退出全屏(监听ESC改样式) 一.效果 二.代码 对监听esc事件和退出全屏问题的解决 vue 的项目中使用了 h5 的全屏 API,在使用esc键退出全屏时,默认调用“ document.exitFullScreen() ” 直接退出,想要做监听并设置业务,需要监听屏幕size变化来出发事件 mounted() {          let that = this     window.addEven

随机推荐