关于vue,记录一次修饰符.stop和.once的使用,以及猜想。

内置指令 | 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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值