事件
一般在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 参数写在所有参数最后。
另外,在 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
阻止事件冒泡
提到事件不得不说到 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({
el: '.container',
methods: {
// fn1 函数触发时会打印 this is outer
fn1: function () {
console.log('this is outer');
},
fn2: function () {
}
}
})
</script>
</body>
代码第 4 行在触发事件之后调用了 stop() 方法,该方法阻止了事件的冒泡,如果去掉 stop 方法结果如下:
当触发内部按钮的点击事件时,该按钮的父级点击事件同样被触发。
如果加入了 stop,结果如下:
阻止默认行为
可以通过 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>