- Vue 的事件系统不同于浏览器的 EventTarget API。尽管它们工作起来是相似的,但是 $emit、$on, 和 $off 并不是 dispatchEvent、addEventListener 和 removeEventListener 的别名
————————————————————————————————————————————————————————
组件外
v-on
- 除了.prevent阻止默认事件还有以下修饰符,.capture(在捕获阶段执行)、.once、.passive(不阻止事件的默认行为,比如滚动事件,当监听滚动事件时不希望替换掉原有的滚动默认行为)
- 不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。
- v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
- 想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on 的 .native 修饰符
<base-input v-on:focus.native="onFocus"></base-input>
(给普通的标签加事件加native是无效的,事件不会被触发)
- 鼠标按钮修饰符
.left .right .middle
- .exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
<button @click.exact="onClick">A</button> <!-- 没有任何系统修饰符被按下的时候才触发 -->
- 可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl .alt .shift .meta
例如:<div @click.ctrl="doSomething">Do something</div> <!-- Ctrl + Click -->
- Vue 允许为 v-on 在监听键盘事件时添加按键修饰符,可以通过全局 config.keyCodes 对象(vue提供)自定义按键修饰符别名。也可直接将 KeyboardEvent.key (KeyboardEvent是js原生提供的键盘事件对象)暴露的任意有效按键名转换为 kebab-case 来作为修饰符(KeyboardEvent.key返回首字母大写单词组,例如:CapsLock。但是有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值)
- 和v-bind一样可以绑定一个对象,例如
v-on="{click:onClick}"
- 对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input 事件。当用输入法时能够捕获输入的每个拼音字母
- 绑定原生事件第一个参数自动带入event对象
@click='do'
,可以使用@click='do($event)'
传入event原生事件对象
- 绑定自定义事件时
@doSome=doSome($event)
$event指向组件内部emit触发时传入的第2个参数this.$emit('doSome','参数2')
- 跟组件和 prop 不同,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。(驼峰和-连接不会自动转换)。v-on如果绑定了驼峰式,会自动转为全部小写。推荐你始终使用 kebab-case 的事件名
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!重点
// 父
<HelloWorld @doSome="clickButton($event)"/>
// 子
this.$emit('doSome','参数还是事件对象') //虽然能够触发自定义事件,但是实际上事件名被转化为dosome容易和未来的事件名冲突,建议改为以下写法
// 父
<HelloWorld @do-some="clickButton($event)"/> // 事件名除了自动转化为小写外不会做其他处理,不管是@时还是emit触发时事件名不匹配(一个为驼峰一个为-链接)都不会触发事件
// 子
this.$emit('do-some','参数还是事件对象')
keyCodes
- Vue 允许为 v-on 在监听键盘事件时添加按键修饰符,可以通过全局 config.keyCodes 对象自定义按键修饰符别名。也可直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符(KeyboardEvent.key返回首字母大写单词组,例如:CapsLock。但是有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值)
Vue.config.keyCodes = {
v: 86,
f1: 112,
// camelCase 不可用
mediaPlayPause: 179,
// 取而代之的是 kebab-case 且用双引号括起来
"media-play-pause": 179,
up: [38, 87]
}
<input type="text" @keyup.media-play-pause="method">
—————————————————————————————————————————————————————————
组件内
vm.$emit
- 当通过
@do-some='doSome'
绑定事件时,只能通过this.$emit('do-some')
触发,不会自动转换为驼峰式
- $emit通过第二个参数抛出数据给父组件(第3个参数接收不到),非原生事件中父组件可以通过 $event 访问到被抛出的这个值,原生事件中$event指向原生事件对象
// 子组件
this.$emit('change-common-data',data)
// 父组件
// 绑定为函数时
...
@change-common-data='changCommonData'
...
...
methods:{
changCommonData(data){
console.log(data)
}
}
...
// 父组件
// 绑定为函数执行时(非原生事件时,$event指向传入的参数)
@chang-common-data='changCommonData($event)' //这里的$event指向$emit传入函数的参数
methods:{
changCommonData(data){
console.log(data) // 打印出来的是emit传入的参数2
console.log(this.$event) // 这样不对
}
}
// 父组件
// 绑定为函数执行时(原生事件时,$event指向原生事件)
@input.native='changCommonData($event)'
methods:{
changeCommonData(data){
console.log(data) // 打印出来的data是个原生事件对象
}
}
vm.$on
- 通过 $on(eventName, eventHandler) 侦听一个事件,eventName可以是字符串或数组(数组只在 2.2.0+ 中支持)
- 该方法绑定事件不会覆盖已经绑定的其他函数
vm.$once
- 通过 $once(eventName, eventHandler) 一次性侦听一个事件
mounted: function () {
var picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'
})
this.$once('hook:beforeDestroy', function () { // 通过动态的侦听事件,可以把创建对象和销毁对象的代码聚合在一个地方,方便维护。实际跟在beforeDestroy钩子下执行是一样效果(这里的事件名很特别)
picker.destroy()
})
}
vm.$off
- 通过 $off(eventName, eventHandler) 停止侦听一个事件,eventName可以是字符串或数组(数组只在 2.2.0+ 中支持)如果没有提供参数,则移除所有的事件监听器;如果只提供了事件,则移除该事件所有的监听器;如果同时提供了事件与回调,则只移除这个回调的监听器。