Webcourse/11-Vue基础/01-02.v-on的事件修饰符.md

264 lines
7.0 KiB
JavaScript
Raw Normal View History

## v-on的事件修饰符
### v-on的常见事件修饰符
`v-on` 提供了很多事件修饰符来辅助实现一些功能事件修饰符有如下
- `.stop` 阻止冒泡本质是调用 event.stopPropagation()
- `.prevent` 阻止默认事件默认行为本质是调用 event.preventDefault()
- `.capture` 添加事件监听器时使用捕获的方式也就是说事件采用捕获的方式而不是采用冒泡的方式
- `.self` 只有当事件在该元素本身比如不是子元素触发时才会触发回调
- `.once` 事件只触发一次
2019-07-28 20:25:12 +08:00
- `.{keyCode | keyAlias}` 只当事件是从侦听器绑定的元素本身触发时才触发回调
2019-07-28 20:25:12 +08:00
- `.native` 监听组件根元素的原生事件
PS一个事件允许同时使用多个事件修饰符
写法示范
```html
<!-- click事件 -->
<button v-on:click="doThis"></button>
<!-- 缩写 -->
<button @click="doThis"></button>
<!-- 内联语句 -->
<button v-on:click="doThat('hello', $event)"></button>
<!-- 阻止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>
<!-- 阻止默认行为没有表达式 -->
<form @submit.prevent></form>
<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>
```
### `.stop`的举例
我们来看下面这个例子
```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>Document</title>
<script src="vue2.5.16.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app">
<div class="father" @click="fatherClick">
<div class="child" @click="childClick">
</div>
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
fatherClick: function () {
console.log('father 被点击了');
},
childClick: function () {
console.log('child 被点击了');
}
}
})
</script>
</body>
</html>
```
上方代码中存在冒泡的现象父标签中包含了一个子标签当点击子标签时父标签也会被触发打印顺序是
```
child 被点击了
father 被点击了
```
那么问题来了如果我不想让子标签的点击事件冒泡到父亲该怎么做呢办法是给子标签加一个**事件修饰符**`.stop`阻止冒泡代码如下
```html
<div class="child" @click.stop="childClick">
```
阻止冒泡后当点击子标签时打印结果是
```
child 被点击了
```
PS我发现一个有意思的现象上方的这行代码中如果把`.stop`改为`:stop`造成的现象是父标签被触发了而子标签没有被触发
### `.capture`举例
`.capture`触发事件时采用捕获的形式而不是冒泡的形式
还是采用上面的例子当按钮点击时如果想要采取捕获的方式而不是冒泡的方式办法是可以直接在父标签上加事件修饰符`.capture`代码如下
```html
<div class="father" @click.capture="fatherClick">
```
当点击子标签时打印结果是
```
father 被点击了
child 被点击了
```
### `.prevent`的举例1
比如说超链接`<a>`默认有跳转行为那我可以通过事件修饰符`.prevent`阻止这种跳转行为
```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>Document</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
<!-- 通过 .prevent 阻止超链接的默认跳转行为 -->
<a href="http://www.baidu.com" @click.prevent="linkClick">百度一下</a>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
linkClick: function () {
console.log('超链接被点击了');
}
}
})
</script>
</body>
</html>
```
上方代码中
- 如果去掉`.prevent`点击按钮后既会打印log又会跳转到百度页面
- 现在加上了`.prevent`就只会打印loeg不会跳转到百度页面
### `.prevent`的举例2
现在有一个form表单
```html
<form action="http://www.baidu.com">
<input type="submit" value="表单提交">
</form>
```
我们知道上面这个表单因为`type="submit"`因此它是一个提交按钮点击按钮后这个表单就会被提交到form标签的action属性中指定的那个页面中去这是表单的默认行为
现在我们可以用`.prevent`来阻止这种默认行为修改为点击按钮后不提交到服务器而是执行我们自己想要的事件在submit方法中另行定义如下
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
<!-- 阻止表单中submit的默认事件 -->
<form @submit.prevent action="http://www.baidu.com">
<!-- 执行自定义的click事件 -->
<input type="submit" @click="mySubmit" value="表单提交">
</form>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
mySubmit: function() {
alert('ok');
}
}
});
</script>
</html>
```
上方代码中我们通过`.prevent`阻止了提交按钮的默认事件点击按钮后执行的是`mySubmit()`方法里的内容这个方法名是可以随便起的我们甚至可以起名为`submit`反正默认的submit已经失效了
### `.self`举例
- `.self` 只有当事件在该元素本身比如不是子元素触发时才会触发回调
我们知道在事件触发机制中当点击子标签时父标签会通过冒泡的形式被触发父标签本身并没有被点击可如果我给父标签的点击事件设置`.self`修饰符达到的效果是子标签的点击事件不会再冒泡到父标签了只有点击符标签本身父标签的事件才会被触发代码如下
```html
<div class="father" @click.self="fatherClick">
```
**疑问**既然`.stop``.self`都可以阻止冒泡那二者有什么区别呢区别在于前者能够阻止整个冒泡行为而后者只能阻止自己身上的冒泡行为