Vue-事件

323 阅读4分钟

事件

一般在vue项目开发中,事件的处理逻辑一般很复杂,我们可以将处理的逻辑变成函数,在vue开发中,一般使用的是使用的是v-on指令进行事件的监听,事件监听的过程中触发相应的JavaScript代码

  • 事件的基本使用

使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名。

事件的回调需要配置在method对象中,最终会在vm上。

methods中配置的函数,不要使用箭头函数,否则this就不是执行vue实例vm了。

methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象。

@click=“demo”和@click=“demo($event)”效果一致,但是后者可以传更多的参数。

事件绑定

Vue 中的事件绑定监听可以使用 v-on 指令进行处理,可以把 v-on 绑定事件简写为 @。语法结构如下:

<button v-on:click='num++'>加一</button>
<button @click='num++'>再加一</button>

第一行代码使用 v-on 进行事件的绑定监听、第二行代码使用 @ 进行事件绑定。如下代码所示:

<body>
    <div class="container">
        <div>{{ num }}</div>
        <button v-on:click='num++'>加一</button>
        <button @click='num++'>再加一</button>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        let vm = new Vue({
            el: '.container',
            data: {
                num: 0,
            }
        })
    </script>
</body>

当点击加一按钮时,页面中的内容 +1。

事件函数的触发

绑定事件的处理函数还可以单独写在 <script> 标签或 JavaScript 文件中,需要在 new Vue 对象时使用 methods 属性进行定义 methods 为一个对象,该对象中包含着处理函数,如下代码所示:

<body>
    <div class="container">
        <div>{{ num }}</div>

        <!-- 绑定单单击事件 -->
        <button v-on:click='add'>加一</button>
        <button @click='add()'>再加一</button>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        let vm = new Vue({
            el: '.container',
            data: {
                num: 0,
            },
            methods: {
                add: function add(params) {
                    this.num++;
                    console.log('点击了');
                }
            }
        })
    </script>
</body>

事件函数的参数

在事件函数中可以传递参数,在事件中设置处理函数有两种方式,这两种方式传递的参数不同。

<button v-on:click='say_hello'>加一</button>
<button @click='say_me("这是第一个参数", "这是第二个参数", $event)'>再加一</button>

上述代码中第一种方式传递的处理函数默认传递的是 event参数,除此参数之外处理函数中不可传递其他参数,第二种方式传递的处理函数最大可以接受255个参数(JS中函数也是如此),需要注意的是,必须把event 参数,除此参数之外处理函数中不可传递其他参数,第二种方式传递的处理函数最大可以接受 255 个参数(JS 中函数也是如此),需要注意的是,必须把 event 参数写在所有参数最后。

另外,在 html 结构中 $event 代表事件对象。

    <div class="container">
        <div>{{ num }}</div>

        <!-- 使用函数名形式绑定的事件函数可以默认传递 $event 事件对象 -->
        <button v-on:click='say_hello'>加一</button>
        <!-- 使用函数调用形式绑定的事件函数可以传递其他参数,$event 必须放在最后 -->
        <button @click='say_me("这是第一个参数", "这是第二个参数", $event)'>再加一</button>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        let vm = new Vue({
            el: '.container',
            data: {
                num: 0,
            },
            // 添加事件处理函数 methods 是一个对象
            methods: {
                say_hello: event => {
                    console.log(event.target);
                },
                say_me: (param1, param2, event) => {
                    console.log(param1);
                    console.log(param2);
                    console.log(event.target);
                }
            }
        })
    </script>
</body>

事件修饰符:Vue认为方法应只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。所以引入了事件修饰符来处理DOM事件。

事件修饰符

阻止默认事件(常用):prevent

阻止事件冒泡(常用):stop

事件只触发一次(常用):once

使用事件的捕获模式:capture

只有event.target是当前操作的元素时才触发事件:self

事件的默认行为是立即执行,无需等待事件回调执行完毕:passive

注意:事件修饰符是可以连续写的,比如@click.stop.prevent

image.png

阻止事件冒泡

提到事件不得不说到 DOM 中事件流的问题,事件流分为三个阶段:捕获、触发、冒泡。其中冒泡阶段会将 DOM 树中的上层事件触发,在 Vue 想要阻止事件的冒泡可以使用 .stop 方法。如下代码所示:

<body>
    <div class="container">
        <div @click="fn1">
            <button @click.stop="fn2">按钮</button>
        </div>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        let vm = new Vue({![事件冒泡](img/事件冒泡.gif)
            el: '.container',
            methods: {
                // fn1 函数触发时会打印 this is outer
                fn1: function () {
                    console.log('this is outer');
                },
                fn2: function () {

                }
            }
        })
    </script>
</body>

代码第 4 行在触发事件之后调用了 stop() 方法,该方法阻止了事件的冒泡,如果去掉 stop 方法结果如下:

当触发内部按钮的点击事件时,该按钮的父级点击事件同样被触发。

如果加入了 stop,结果如下:

image.png

阻止默认行为

可以通过 DOM 中时间对象的 preventDefault() 方法来阻止某些特定元素的默认行为。

Vue 同样提供了 prevent 方法来阻止默认行为,如下代码所示:

<body>
    <div class="container">
        <a @click.prevent href="https://www.baidu.com">百度</a>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        let vm = new Vue({
            el: '.container',
        })
    </script>
</body>

需要注意,参见 Vue 事件修饰符 下文中的警告:

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

捕获事件

这个修饰符所修饰的事件流是捕获事件流,这个DOM事件流分成冒泡事件流和捕获事件流两个事件,而我们现在讲的capture所修饰的事件流就是捕获事件流。我们还是通过一段程序来理解:

代码实例:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>数据双向绑定</title>
    <script src="http://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
    <div id="app">
<div @click.capture="box" :style="{border:'solid 2px black'}">
    <a href="http://www.taobao.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" @click.stop.prevent="links">淘宝</a>
</div>
    </div>
    <script>
var app = new Vue({
    el:'#app',
    methods:{
box(){
    alert('div盒子');
},
links(){
    alert('http://www.淘宝.com');
}
    }
})
    </script>
</body>
</html>

self修饰符

个修饰符只是用来接收自己触发的事件函数,只有绑定这个事件的元素触发事件的时候,才会触事件的处理函数,而且这个事件不会被冒泡或者被捕获。我们通过实例代码了解一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>数据双向绑定</title>
</head>
<body>
    <div id="app">
<div @click.self="box()" id="box">
<input type="button" value="按键"@click="btn()">
</div>
    </div>
    <script src="http://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    <script>
var vm = new Vue({
    el:'#app',
    methods:{
box(){
console.log("div");
},
btn(){
    console.log("button");
}
    }
})
    </script>
</body>
</html>

我们可以看到通过单击只会出现“button”,按键的单击事件触发,div没有接收到冒泡,div上面的单击事件没有被触发。通过单击div,只能输出“div”div的单击事件被触发,但是按键的单击事件没有被触发。

键盘事件

Vue中常用的按键别名:
回车:enter
删除:delete (捕获“删除”和“退格”键)
退出:esc
空格:space
换行:tap (特殊,必须配合keydown去使用)
上:up
下:down
左:left
右:right
Vue中未提供的别名按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)。

系统修饰符(用法特殊):ctrl, alt,shift, meta

配合keyup使用:按下修饰符的同时,再按下其他键,随后释放其他键,时间才被触发。
配合keydown使用,正常触发事件。
也可以使用keyCode键码去指定具体的按键(不推荐,因为该特性已从web中移除了,未来可能不再支持)。

Vue.config.keyCode.自定义键名=键码。可以去定制按键别名。(不太推荐,一般默认的也就够用了)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>键盘事件</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
        <style>
           
        </style>
    </head>
    <body>
       <div id="root">
           <h2>欢迎来到{{name}}学习</h2>
           <input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo"><br/>
           <input type="text" placeholder="按下CapsLock提示输入" @keyup.caps-lock="showInfo"><br/>
           <input type="text" placeholder="按下tab提示输入" @keydown.tab="showInfo"><br/>
           <input type="text" placeholder="按下ctrl+任意键,抬起任意键提示输入" @keyup.ctrl="showInfo"><br/>
           <input type="text" placeholder="按下ctrl提示输入" @keydown.ctrl="showInfo"><br/>
           <input type="text" placeholder="通过键码绑定事件" @keydown.13="showInfo">
           <input type="text" placeholder="vue自定义按键别名" @keydown.huiche="showInfo">
           <br/>
           <br/>
           <input type="text" placeholder="按下ctrl+y键触发" @keydown.ctrl.y="showInfo">
         
        </div>
        
        <!--阻止vue在启动时生成生产提示 -->
        <script type="text/javascript">
        Vue.config.productionTip=false
        // vue自定义按键别名
        Vue.config.keyCodes.huiche=13
        const vm = new Vue({
            el: "#root",
            data:{
                name:"Gitlink",
            },
            methods:{
                showInfo(event){
                    // 输出按键编码
                    // console.log(event.keyCode)
                    // 输出输入框中输入的值
                    // console.log(event.target.value)
                    // js写法
                    // if(event.keyCode !== 13) return
                    console.log(event.target.value)
                    // 输出按键的名称以及编码
                    console.log(event.key)
                }
               
                
            }
        })
        </script>
       
    </body>
</html>