内置指令 | Vue.js
在vue的api里,关于v-on有stop和once两个事件标签。
.stop
- 调用event.stopPropagation()
。.once
- 最多触发一次处理函数。
原有主要代码和页面效果 (无stop和once):
...
<div class="div" @click="divClick()">
<p class="p" @click="pClick()"></p>
</div>
...
<script>
...
divClick(){
console.log('div点击了');
},
pClick(){
console.log('p点击了');
}
...
</script>
.stop
stop用于在页面表单中,只触发子元素,不触发父元素的操作。例如:
<div class="div" @click="divClick()">
<p class="p" @click.stop="pClick()"></p>
</div>
效果如下。p元素(绿区)绑定了pClick的指令,p元素是div元素(背景红区)的子元素,div也绑定了一个事件。点击p元素,div所绑定的事件没有被触发。
.once
once
用于在页面表单中,只触发子元素,不触发父元素的操作。例如:
<div class="div" @click="divClick()">
<p class="p" @click.once="pClick()"></p>
</div>
效果如下。p元素(绿区)绑定了pClick的指令,p元素是div元素(背景红区)的子元素,div也绑定了一个事件。点击p元素两次,p所绑定的事件只触发了一次,div所绑定的事件两次被触发。
.stop.once或者.once.stop:
代码如下:
<div class="div" @click="divClick()">
<p class="p" @click.stop.once="pClick()"></p>
</div>
效果如下:
第一次点击绿区p,只触发了绿区p的事件,没有触发红区div的事件。
第二次点击绿区p,没有触发了绿区p的事件,但是触发了红区div的事件。
点击绿区p第三次,同样只触发红区div的事件,不触发绿区p的事件。
将.stop.once改成.once.stop得到的也是一样的结果。
...
<div class="div" @click="divClick()">
<p class="p" @click.once.stop="pClick()"></p>
</div>
...
...
pClick(){
console.log('p点击了 .once.stop');
},
...
猜想:
stop的作用是不触发当前处理函数所在元素的父级元素处理函数,once的作用是最多触发一次处理函数。当.stop.once混用的时候,第一次点击stop和once都对当前元素的函数,其作用范围只在当前元素上。但是第二次点击的时候,stop不再起作用了,父级元素可以被多次触发。
因此我猜测,once这个修饰符,在第一次点击执行后,对当前元素做了去除操作(不知道是逻辑去除还是物理去除,个人偏向物理)。这个操作不仅会去除该元素绑定的处理函数,还会去除该元素上带有的其他修饰符。
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件</title>
<script src="../../public/script/vue_2.2.2.min.js"></script>
<style>
.div{
width: 200px;
height: 200px;
background-color: red;
margin-top: 20px;
}
.div2{
width: 200px;
height: 200px;
background-color: yellow;
margin-top: 20px;
}
.p{
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div id="app">
<button @click="add('horse',$event)">加一马</button>
<input type="text" :value="age" />
<button @click="sub()">减一马</button>
<div class="div" @click="divClick()">
<p class="p" @click.once.stop="pClick()"></p>
</div>
<div class="div2" @click="divClick()">
<p @click.stop.once="aClick()" target="_blank">Baidu一下</p>
</div>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
name: 'Calven',
age: 24,
wechat: 'CalvenZeng'
},
methods: {
add(msg, event){
this.age++;
console.log(msg);
console.log(event);
},
sub(){
this.age--;
},
divClick(){
console.log('div点击了');
},
pClick(){
console.log('p点击了 .once.stop');
},
aClick(){
console.log('a点击了');
window.open("https://www.baidu.com", "baidu");
}
}
});
</script>
</body>
</html>