叉烧店并不卖叉烧

事件处理

vuejs TTT 64℃ 0评论

参考

事件监听

可以用v-on指令监听DOM事件,并触发时运行一些JavaScript代码。

示例:

<div id="app-56">
	<button v-on:click="counter += 1">Add 1</button>
	<p>The button above has been clicked {{ counter }} times.
</div>
new Vue({
	el: '#app-56',
	data: {
		counter: 0
	}
})

结果:

The button above has been clicked {{ counter }} times.

事件处理方法

然而许多事件处理逻辑会更加复杂,所以直接把JavaScript代码写在v-on指令中是不可行的。因此v-on还可以接收一个需要调用的方法名称。

示例:

<div id="app-57">
	<!-- `greet` 是在下面定义的方法名 -->
	<button v-on:click="greet">Greet</button>
</div>
var app57 = new Vue({
	el: '#app-57',
	data: {
		name: 'Vue.js'
	},
	methods: {
		greet: function (event) {
			// `this` 在方法里指向当前的Vue实例
			alert('Hello ' + this.name + '!')
			// `event`是原生DOM事件
			if (event) {
				alert(event.target.tagName)
			}
		}
	}
})
// 也可以用 JavaScript 直接调用方法
app57.greet() // => 'Hello Vue.js!'

结果


内联处理器中的方法

除了直接绑定到一个方法,也可以在内联JavaScript语句中调用方法:

<div id="app-58">
	<button v-on:click="say('hi')">say hi</button>
	<button v-on:click="say('what')">say what</button>
</div>
var app58 = new Vue({
	el: '#app-58',
	methods: {
		say: function (msg) {
			alert(msg)
		}
	}
})

有时也需要在内联语句处理器中访问原始的DOM事件。可以使用特殊变量$event把它传入方法:

<div id="app-59">
	<button v-on:click="warn('Form cannot be submitted yet.', $event)">
		submit
	</button>
</div>
var app59 = new Vue({
	el: '#app-59',
	methods: {
		warn: function (msg, event) {
			// 现在我们就可以访问原生事件对象
			if (event) event.preventDefault()
			alert(msg)
		}
	}
})

事件修饰符

在事件处理程序中调用event.preventDefault()或者event.stopPropagation()是非常常见的需求。尽管我们可以在方法中轻松实现这点,但
更好的方式是:方法只有纯粹的数据逻辑,而不去处理DOM事件细节。

为了解决这个问题,Vue.js为v-on提供了事件修饰符。之前提过,修饰符
是由点开头的指令后缀来表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<div id="app-60">
	<!-- 阻止单击事件继续传播 -->
	<a href="#" v-on:click.stop="doThis">doThis</a>
	<!-- 提交事件不再重载页面 -->
	<form v-on:submit.prevent="onSubmit" action="#" method="post">
		<button type="submit">onSubmit</button>
	</form>
	<!-- 修饰符可以串联 -->
	<a href="#" v-on:click.stop.prevent="doThat">doThat</a>
	<!-- 只有修饰符 -->
	<form v-on:submit.prevent>
		<button type="submit">empty</button>
	</form>
	<!-- 添加事件监听器时使用事件捕获模式 -->
	<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
	<div v-on:click.capture="doThis2">doThis2</div>
	<!-- 只当在event.target是当前元素自身时触发处理函数 -->
	<!-- 即事件不是从内部元素触发的 -->
	<div v-on:click.self="doThat2">doThat2</div>
</div>
var app60 = new Vue({
	el: '#app-60',
	methods: {
		doThis: function () {
			alert('doThis')
		},
		onSubmit: function () {
			alert('prevent submit')
		},
		doThat: function () {
			alert('doThat')
		},
		doThis2: function () {
			alert('doThis2')
		},
		doThat2: function () {
			alert('doThat2')
		}
	}
})
使用修饰符,顺序很重要;相应的代码会以同样的顺序产生。因此,用v-on:click.prevent.self会阻止所有的点击,而v-on:click.self.prevent只会阻止对元素自身的点击。

2.1.4新增

<div id="app-61">
	<!-- 点击事件将只会触发一次 -->
	<a href="#" v-on:click.once="doThis">doThis</a>
</div>
var app61 = new Vue({
	el: '#app-61',
	methods: {
		doThis: function () {
			alert('doThis')
		}
	}
})

不像其他只能对原生DOM事件起作用的修饰符,.once修饰符还能用到自定义的组件事件上。如果还没有阅读关于组件的文档,现在大可不必担心。

2.3.0新增

Vue还对应addEventListener中的passive选项提供了.passive修饰符。

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

这个.passive修饰符尤其能够提升移动端的性能。

不要把.passive.prevent一起使用,因为.prevent将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive会告诉浏览器你想阻止事件的默认行为。

按键修饰符

在监听键盘事件时,我们经常需要检查常见的键值。Vue允许为v-on在监听键盘事件时添加按键修饰符:

<div id="app-62">
	<!-- 只有在`keyCode`是13时调用`vm.submit()` -->
	<input v-on:keyup.13="submit13"/>
</div>
var app62 = new Vue({
	el: '#app-62',
	methods: {
		submit13: function () {
			alert('submit13')
		}
	}
})

记住所有的keyCode比较困难,所以Vue为最常用的按键名提供了别名:

<div id="app-62">
	<!-- 只有在`keyCode`是13时调用`vm.submit()` -->
	<input v-on:keyup.13="submit13"/>
	<!-- 同上 -->
	<input v-on:keyup.enter="enter"/>
	<!-- 缩写语法 -->
	<input @keyup.enter="simple"/>
</div>
var app62 = new Vue({
	el: '#app-62',
	methods: {
		submit13: function () {
			alert('submit13')
		},
		enter: function () {
			alert('enter')
		},
		simple: function () {
			alert('simple')
		}
	}
})

全部的按键别名:

  • .enter
  • .tab
  • .delete(捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

可以通过全局config.keyCodes对象自定义按键修饰符别名

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

自动匹配按键修饰符

2.5.0新增

?你也可以直接将KeyboardEvent.key暴露的任意有效按键名转换为kebab-case来作为修饰符?!

<input @keyup.page-down="onPageDown">

在上面的例子中,处理函数仅在$event.key === 'PageDown'时被调用。

有一些按键(.esc以及所有的方向键)在IE9中有不同的key值,如果你想支持IE9,它们的内置别名应该是首选。

系统修饰键

2.1.0新增

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
  • .meta
注意:在Mac系统键盘上,meta对应command键 (⌘)。在Windows系统键盘meta对应Windows徽标键(⊞)。在Sun操作系统键盘上,meta对应实心宝石键 (◆)。在其他特定键盘上,尤其在MIT和Lisp机器的键盘、以及其后继产品,比如Knight键盘、space-cadet键盘,meta被标记为“META”。在Symbolics键盘上,meta被标记为“META”或者“Meta”。

例如:

<div id="app-64">
	<!-- Alt + C -->
	<input @keyup.alt.67="clear" placeholder="Alt + C"/>
	<!-- Ctrl + Click -->
	<div @click.ctrl="clickCtrl">clickCtrl</div>
</div>
var app64 = new Vue({
	el: '#app-64',
	methods: {
		clear: function () {
			alert('clear')
		},
		clickCtrl: function () {
			alert('clickCtrl')
		}
	}
})
请注意修饰键与常规按键不同,在和keyup事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住ctrl的情况下释放其他按键,才能触发keyup.ctrl。而单单释放ctrl也不会触发事件。如果你想要这样的行为,请为ctrl换用keyCodekeyup.17

.exact修饰符

2.5.0新增

.exact修饰符允许你控制由精确的系统修饰符组合触发的事件。

<div id="app-65">
	<!-- 即使Alt或Shift被一同按下时也会触发 -->
	<button @click.ctrl="clickCtrl">clickCtrl</button>
	<!-- 有且只有Ctrl被按下的时候才触发 -->
	<button @click.ctrl.exact="clickCtrlExact">clickCtrlExact</button>
	<!-- 没有任何系统修饰符被按下的时候才触发 -->
	<button @click.exact="clickExact">clickExact</button>
</div>
var app65 = new Vue({
	el: '#app-65',
	methods: {
		clickCtrl: function () {
			alert('clickCtrl')
		},
		clickCtrlExact: function () {
			alert('clickCtrlExact')
		},
		clickExact: function () {
			alert('clickExact')
		}
	}
})

鼠标按钮修饰符

2.2.0新增

  • .left
  • .right
  • .middle

这些修饰符会限制处理函数仅响应特定的鼠标按钮。

<div id="app-66">
	<button @click.left="clickLeft">clickLeft</button>
	<!-- 增加.prevent是为了阻止显示浏览器菜单 -->
	<button @click.right.prevent="clickRight">clickRight</button>
	<button @click.middle="clickMiddle">clickMiddle</button>
</div>
var app66 = new Vue({
	el: '#app-66',
	methods: {
		clickLeft: function () {
			alert('clickLeft')
		},
		clickRight: function () {
			alert('clickRight')
		},
		clickMiddle: function () {
			alert('clickMiddle')
		}
	}
})

为什么在HTML中监听事件?

??!

你可能注意到这种事件监听的方式违背了关注点分离(separation of concern)这个长期依赖的优良传统。但不必担心,因为所有的Vue.js事件处理方法和表达式都严格绑定在当前视图的ViewModel上,它不会的导致任何维护上的困难。实际上,使用v-on有几个好处:

1.扫一眼HTML模板便能轻松定位在JavaScript代码里面的对应方法。

2.因为你无需再JavaScript里手动绑定事件,你的ViewModel代码可以时非常纯粹的逻辑,和DOM完全解耦,更易于测试。

3.当一个ViewModel被销毁时,所有的事件处理器都会被自动删除。我们无须担心如何清理它们。

转载请注明:叉烧店 » 事件处理

喜欢 (0)
发表我的评论
取消评论

CAPTCHA Image
Reload Image
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址