Vue 组件上的类似 DOM 事件那点事儿

click 是事件.

事件是基本的 DOM 元素都具备的一个特性.

一个 DOM 元素不管是否绑定了事件响应函数.

只要我们点击了(或者触摸了)这个 DOM 元素.那么在其内部一定就会发出一个对应的事件信号.

<div></div>
<button></button>
<p></p>
<span></span>
.....

div.onclick = function () {}
button.onclick = function () {}
p.onclick = function () {}
span.onclick = funciton () {}
....

组件上的 click

首先组件是一个 js 对象.

里面包含了一堆和当前组件相关的数据和函数.

HelloWorld.vue

- data () {}
- methods: {}
- watch: {}
- computed: {}
- components: {}
....

当在语法级别,我们给定一个第三方组件绑定 click 事件时.

<cube-button @click="hanlderClick"><cube-button>

并在当前组件内部定义事件响应函数

HelloWorld.vue

methods: {
    hanlderClick () {
        console.log('点击 cube-button 事件将被触发.')
    }
}

点击 cube-button 时,事件将被触发,乍看之下,感觉这很符合直觉.

(本来就是写的一堆跑浏览器下的玩意,click 事件不是很常见吗?)

但是稍微深入思考一下,就会发现问题所在了.


往组件上绑定事件到底是在干什么?

已经知道了,组件本身是一个 js 对象.

我们在组件上绑定 @click 事件,翻译一下就是: 往组件上绑定 click 事件.

现在的问题是,一个普通的 js 对象 Object.

它是不具备 click 事件特性的.

它不可见,它是数据,用户根本就不可能想普通的 HTML 元素那样用肉眼看到它.

看不到它,怎么可能去点击它.就更不可能有 click 这个存在于肉眼可见的 DOM 元素上了.

所以,能够触发 click 事件的,肯定是组件内部以某种方式向外发布了 click 事件.$emit

1. 直接在组件上绑定 click 事件.

<div id='app'>
    <!--直接在组件上绑定 click 事件,并没有任何效果.-->
    <comp-one @click="handlerClick" content="Hello Click"></comp-one>
</div>
const CompOne = {
    template:`<div :style="styleObj" >{{content}}</div>`,
    props:['content']
}
 var app = new Vue({
    el: '#app',
    data: {},
    methods: {
      handlerClick () {
        console.log('写在组件上的 click')
      }
    }
}

点击组件发现并没有任何效果:

组件直接绑定事件没有任何结果

2.当组件内部任意一个可以被用户点击到的 DOM 元素发布一个 click 事件

const CompOne = {
    template:`<div :style="styleObj" @click="hanlderClick">{{content}}</div>`,
    props:['content'],
    methods: {
      hanlderClick () {
        this.$emit('click') // 最外层 DIV 元素看的到,用户点击这个 div,手动的向外部发送 click 事件.
      }
    }
}

结果:

内部手动的给组件的某个 HTML 元素绑定 click,然后在 clickhanlder 内向外发布 click 事件

结论:在组件上监听click事件的本质是,被监听事件的组件内部,无论以何种方式,必须想外部$emit 出 click 事件信号才可以.

  • 常规方式是,利用组件内模板用户可视可操作的某个 DOM 元素点击的时候触发 $emit('click')
  • 不常规做法是,不利用上述这种的任意其他方式.比如定时器.

3.@click.native

如果,我们直接在组件上使用 @click 就必须手动的在被监听了 click 的组件内部调用 $emit.

而 @click.native 修饰符则就是帮我们做了一件事情而已.

在被监听了 @click 的组件内部的 DOM 根元素上自动的注册 click 事件.

并定义 clickHanlder .

在此 clickHanlder 内,触发 this.$emit('click')

<div 420123456='app'>
    <!-- 组件内部 根元素 click=>{this.$emit('click')} -->
    <comp-one @click.native="handlerClick" content="Hello Click"></comp-one>
  </div>
  
 const CompOne = {
    // template:`<div :style="styleObj" @click="hanlderClick">{{content}}</div>`, // @cilck.native 等价 @click = clickhanlder
    template:`<div :style="styleObj">{{content}}</div>`, // 内部不需要在手动的注册并调用 click 事件响应函数了
    props:['content'],
    methods: {
      // hanlderClick () { // @cilck.native 等价 @click = clickhanlder
      //   this.$emit('click')
      // }
    }
}

 var app = new Vue({
    el: '#app',
    data: {},
    methods: {
      handlerClick () {
        console.log('写在组件上的 click')
      }
    }
}

结果

@click.native 默认就是帮我们做了:组件根元素绑定 click,提供 clickhandler,在 clickhandler 内部发布 click 仅此而已

关于组件上定义 DOM 事件说明

  • 和在组件上定义任意事件本质上一样的.(不管是 DOM.click, 还是 whateverEvent). 都是需要组件内部去触发.
  • 例子里定义的 click ,对于组件来说,不存在这样的事件,组件本身是一个 Object 对象,不可视元素,是数据,用户根本无法操作它,更加不会有 click 事件了.所以需要靠内部的不管是 DOM 也好,其他方式也罢,在某个时刻触发 click 事件 (this.$emit('click'))
  • 对于原生的 DOM 事件来说,@click.native 的 native 修饰符,Vue 默认值是帮我们在组件的根模板元素上绑定了 click 函数,就是DOM元素本身可以发布click事件的机制.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容