实验介绍
在平常开发中,对 DOM 的操作很常见,然而 Vue 中是虚拟 DOM 不太提倡直接进行原生 DOM 操作,降低性能。在 Vue 中可以使用 v-on 指令来操作 DOM 事件。
知识点
- 事件绑定指令
- 事件处理方法
- 内联方法
- 修饰符
事件监听
我们来看个事件监听的简单示例—计数器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>syl-vue-test</title>
<!-- 引入 vue.js -->
<script src="vue.min.js"></script>
<style>
button {
width: 150px;
height: 40px;
border-radius: 10px;
background: green;
outline: none;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<!-- v-on:click 绑定点击监听 点一次 counter 累加一次-->
<button v-on:click="counter+=1">点击</button>
<p>你点了{{counter}}次</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
counter: 0,
},
});
</script>
</body>
</html>
试一试你的手速,运行效果:
事件监听处理方法
许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。该方法写在 methods 对象中。
methods 对象中实现方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>syl-vue-test</title>
<!-- 引入 vue.js -->
<script src="vue.min.js"></script>
<style>
button {
width: 150px;
height: 40px;
border-radius: 10px;
background: green;
outline: none;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<!-- 绑定点击监听 -->
<button v-on:click="say">点击</button>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
counter: 0,
},
methods: {
// 声明事件点击监听 say 方法
say: function (event) {
// 监听事件回调处理 event.type 触发事件类型 说明:`${}` 为 es6 模板字符串,拼接字符串的
alert(`小楼提醒:你触发了${event.type}事件`);
},
},
});
</script>
</body>
</html>
运行结果:
内联处理器的方法
不同元素触发同一事件或不同事件,调用同用一个方法。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>syl-vue-test</title>
<!-- 引入 vue.js -->
<script src="vue.min.js"></script>
<style>
button {
width: 150px;
height: 40px;
border-radius: 10px;
background: green;
outline: none;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<!-- 绑定点击监听 共用 say 方法-->
<button v-on:click="say('实验楼')">实验楼</button>
<button v-on:click="say('小楼')">小楼</button>
</div>
<script>
var app = new Vue({
el: "#app",
data: {},
methods: {
// 声明事件点击监听 say 方法
say: function (name) {
alert(`我是${name}`);
},
},
});
</script>
</body>
</html>
运行结果:
事件修饰符
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求,阻止事件冒泡或捕获或者事件默认行为。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on 提供了 事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
- .stop:阻止单击事件继续传播。
- .prevent:阻止事件默认行为。
- .capture:添加事件监听器时使用事件捕获模式。
- .self:只当在 event.target 是当前元素自身时触发处理函数。
- .once:点击事件将只会触发一次。
- .passive:滚动事件的默认行为 (即滚动行为) 将会立即触发。
例子:
.stop 修饰符的应用。
未添加 .stop 修饰符,事件会触发冒泡行为,点击子元素也会触发父元素的相同事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>syl-vue-test</title>
<!-- 引入 vue.js -->
<script src="vue.min.js"></script>
<style>
/* 居中 */
.super,
.child {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
}
.super {
width: 300px;
height: 300px;
background: pink;
}
.super .child {
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="app">
<div class="super" v-on:click="handleClick('super')">
父
<div class="child" v-on:click="handleClick('child')">子</div>
</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {},
methods: {
// 声明事件点击监听 handleClick
handleClick: function (name) {
alert(`我是${name}`);
},
},
});
</script>
</body>
</html>
运行效果:
添加修饰符:
<div id="app">
<div class="super" v-on:click.stop="handleClick('super')">
父
<div class="child" v-on:click.stop="handleClick('child')">子</div>
</div>
</div>
成功阻止事件冒泡,运行结果:
按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
.enter例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>syl-vue-test</title>
<!-- 引入 vue.js -->
<script src="vue.min.js"></script>
</head>
<body>
<div id="app">
<input
type="text"
v-on:keyup.enter="alert('你按了enter,确定输入完毕?')"
/>
</div>
<script>
var app = new Vue({
el: "#app",
});
</script>
</body>
</html>
运行结果: