# 事件监听
# 使用
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<div id="app">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
<script src="/lib/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
counter: 0,
},
methods: {},
});
</script>
</body>
</html>
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法
- 情况1:方法定义时没有参数要接收,调用方法后不加
()或添加()都没关系 - 情况2:方法定义时只想接收一个原生 DOM 事件
event参数,调用方法不能加(),默认会传递event参数。若添加了(),将不会传递event参数。也可以添加($event)来传递(不过没必要)。 - 情况3:方法定义时有自定义参数,则调用方法时必须传递参数
(params...)。若还需要event参数,调用时可传递(params,$event)参数
具体查看下面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<div id="app">
<button v-on:click="counter1 += 1">button1</button>
<p>The button1 above has been clicked {{ counter1 }} times.</p>
<!-- 不传递参数 -->
<button @click="increment2">button2</button>
<p>The button2 above has been clicked {{ counter2 }} times.</p>
<!-- 传递event -->
<button @click="increment3">button3</button>
<p>The button3 above has been clicked {{ counter3 }} times.</p>
<!-- 传递参数 -->
<button @click="increment4(5)">button4</button>
<p>The button4 above has been clicked {{ counter4 }} times.</p>
<!-- 传递参数+event -->
<button @click="increment5(5,$event)">button5</button>
<p>The button5 above has been clicked {{ counter5 }} times.</p>
</div>
<script src="/lib/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
counter1: 0,
counter2: 0,
counter3: 0,
counter4: 0,
counter5: 0,
},
methods: {
// 不传递参数
increment2() {
this.counter2++;
},
// 传递event
increment3(event) {
this.counter3++;
// `event` 是原生 DOM 事件
if (event) {
console.log(event);
alert(event.target.tagName);
}
},
// 传递参数
increment4(num) {
alert(num);
this.counter4++;
},
// 传递参数+event
increment5(num, event) {
alert(num);
this.counter5++;
// `event` 是原生 DOM 事件
if (event) {
console.log(event);
alert(event.target.tagName);
}
},
},
});
// 也可以用 JavaScript 直接调用方法。一般不用
// vm.increment2();
</script>
</body>
</html>
# 事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。
Vue.js通过由点.表示的指令后缀来调用修饰符:
.stop:停止事件传播,不再派发事件.prevent:停止事件的默认动作.capture.self.once
# .stop
停止事件传播,不再派发事件(冒泡)。底层为 JS 原生调用 event.stopProgatation()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<div id="app">
.stop
<div @click="divClick">
div<button @click.stop="btnClick">btn</button>
</div>
</div>
<script src="/lib/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
message: "Hello",
},
methods: {
divClick() {
console.log("divClick");
},
btnClick() {
console.log("btnClick");
},
},
});
</script>
</body>
</html>
# .prevent
停止事件的默认动作,如表单提交。底层为 JS 原生调用 event.preventDefault()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<div id="app">
.prevent
<form action="http://www.qq.com" method="post" @submit.prevent>
<!--.prevent-->
<input type="submit" value="提交" />
</form>
<form action="http://www.baidu.com" method="post">
<!--.prevent-->
<input type="submit" value="提交" @click.prevent="submitClick" />
</form>
<hr />
</div>
<script src="/lib/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
message: "Hello",
},
methods: {
submitClick() {
console.log("submitClick");
},
},
});
</script>
</body>
</html>
原生实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<form action="http://www.qq.com" method="post" onsubmit="return checkForm();">
<input type="submit" value="提交">
</form>
<script>
function checkForm() {
return false;
};
</script>
</body>
</html>
# .once
事件将只会触发一次
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<div id="app">
.once
<button @click.once="onceClick">OnceClick</button>
</div>
<script src="/lib/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
message: "Hello",
},
methods: {
onceClick() {
console.log("onceClick");
},
},
});
</script>
</body>
</html>
# 按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
全部的按键别名:
.enter.tab.delete(捕获 "删除" 和 "退格" 键).esc.space.up.down.left.right.ctrl.alt.shift.meta
# .enter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<div id="app">
.enter
<input type="text" @keyup.enter="keyUp" />
</div>
<script src="/lib/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
message: "Hello",
},
methods: {
keyUp() {
// 未使用.enter前,任何按键keyup都会触发
console.log("keyUp.按了回车");
},
},
});
</script>
</body>
</html>
# .native 组件
监听组件根元素的原生事件