事件传参
关于事件处理之前已经接触过v-on
,用来监听一个DOM事件然后触发执行JavaScript语句,然而很多事件处理的js代码比较复杂,所以直接写在v-on
中会使得整体变得臃肿,所以v-on
还可以直接接收一个方法名称,提高了代码的复用性。
原生DOM事件
首先我们了解一下原生DOM事件内容,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
methods: {
clickH1(e){
console.log(e)
}
},
})
</script>
- 第12行绑定点击事件,触发打印原生DOM事件
测试页面:
部分打印内容如下,在e.target下有tagName,表明DOM对象的标签名,其实很多信息都存在了原生的target属性下
Vue事件传参
上面介绍了打印原生DOM事件出现的内容,现在我们需要实现传递一个值给该标签,当我们点击标签时,直接在控制台输出该值,可以在v-on
或者@
中使用(实参)
来传递参数给之前的e对象,这样直接覆盖了原生DOM内容。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(事件1)">点击查看1</h1>
<h1 @click="clickH1(事件2)">点击查看2</h1>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
methods: {
clickH1(e){
console.log(e)
}
},
})
</script>
- 第12、13行在
@click
中使用括号传递了两个字符串分别为:"事件1"、"事件2"。 - 接22行是使用形参e接收12、13行括号中传递的参数,而不是之前原生的DOM事件。
测试页面:
可以看到不是原生DOM事件。
如果想既传递传参,又查看原生DOM事件,使用特殊变量$event
传入方法,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(123,$event)">点击打印传递的参数123</h1>
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
methods: {
clickH1(e,event){
console.log(e);
console.log(event);
}
},
})
</script>
- 第12行添加新的参数
$event
- 第21行方法添加形参event接受
$event
测试页面:
观察控制台可以看到传递的参数和原生DOM事件都打印在控制台。
自定义参数名
在模板中,制定传递的参数的参数名,使用data-参数名="value"
方法来传递自定义参数,在被调用的函数中,使用$event.currentTarget.dataset.参数名
来获取自定义的参数。
例如:
<div id="app">
<div
data-id="123"
@click='add'
>{{ message }}</div>
</div>
<script>
var app = new Vue({
el: '#app',
data () {
return {
message: 'Hello Vue!'
}
},
methods: {
add(e){
console.log('currentTarget:',e.currentTarget.dataset);
}
}
})
</script>
运行结果:
注意:如果@click="函数名"
中,函数名不带括号,则会自动注入$event对象,此时e.currentTarget存在,如果带有括号,则需要将$event作为参数,才能访问到$event对象。
事件修饰符
官方文档:
https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6
事件修饰符是用来对执行事件动作进行一些规定,比如只允许事件执行一次、提交事件不重新加载页面等等。
.stop
- 阻止单击事件传播
.prevent
- 不再重新加载页面
.capture
- 添加事件监听器时使用事件捕获模式
.self
.once
- 只允许事件执行一次
.passive
并且修饰符可以串联使用,而且需要注意修饰符的先后执行顺序。
.once
.once
只允许事件触发一次,如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(123,$event)">点击打印传递的参数123</h1>
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
<button @click.once="clickBtn">按钮</button>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
methods: {
clickH1(e,event){
console.log(e)
console.log(event)
},
clickBtn(){
alert(123)
}
},
})
</script>
- 第14行添加按钮标签,然后使用
.once
修饰符,绑定clickBtn
方法 - 26-28行新建一个方法触发弹窗事件。
测试页面:
多次点击按钮,只有第一次触发弹窗事件。
.stop
.stop
是用来阻止冒泡事件发生,阻止事件向父级标签传播
了解什么是冒泡事件可以查看之前学习微信小程序的一篇文档:https://www.yuque.com/justinpeiqi/dr9dgm/xdgl1l
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(123,$event)">点击打印传递的参数123</h1>
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
<button @click.once="clickBtn">按钮</button>
<hr>
<div class="out" @click="clickOut" style="width: 400px;
height: 400px;background-color: pink;">
<div class="box" @click="clickBox" style="width: 100px;
height: 100px;background: orange;">
box
</div>
</div>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
methods: {
clickH1(e,event){
console.log(e)
console.log(event)
},
clickBtn(){
alert(123)
},
clickOut(){
console.log("out")
},
clickBox(){
console.log("box")
}
},
})
</script>
- 16-22行创建了嵌套的区域,粉色区域包含橙色区域,并且每个区域绑定了各自的方法,当点击区域时会打印对应的内容
- 37-42行两个方法对应打印各自区域名
在未使用.stop
情况下,点击橙色区域,发现橙色和粉色区域事件都触发了,就是说原本只想点击橙色区域,但是橙色被粉色包含,所以事件还传递给了父级粉色,导致粉色事件也触发。
所以有时为了避免冒泡事件的发生,在vue中使用.stop
来阻止事件向父级标签传递,这也是面试时的一个常见的问题。
现在添加.stop
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(123,$event)">点击打印传递的参数123</h1>
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
<button @click.once="clickBtn">按钮</button>
<hr>
<div class="out" @click="clickOut" style="width: 400px;height: 400px;background-color: pink;">
<div class="box" @click.stop="clickBox" style="width: 100px;height: 100px;background: orange;">
box
</div>
</div>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
methods: {
clickH1(e,event){
console.log(e)
console.log(event)
},
clickBtn(){
alert(123)
},
clickOut(){
console.log("out")
},
clickBox(){
console.log("box")
}
},
})
</script>
- 第17行添加
.stop
添加了.stop
阻止事件向外传递,测试页面:
可以发现点击橙色区域只触发了本区域的事件,而其父级事件没有被触发。
.prevent
.prevent
可以用来直接阻止input
内容被提交,.prevent
也可以绑定方法,等待方法执行完成之后再去提交内容,这样可以使用方法对填写的内容进行验证,比如验证是否为空,验证数据格式是否规范,等验证通过之后再提交至目标对象。
1.0例子
例如以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(123,$event)">点击打印传递的参数123</h1>
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
<button @click.once="clickBtn">按钮</button>
<hr>
<div class="out" @click="clickOut" style="width: 400px;height: 400px;background-color: pink;">
<div class="box" @click.stop="clickBox" style="width: 100px;height: 100px;background: orange;">
box
</div>
</div>
<form @submit.prevent="onSubmit">
<input type="text" v-model="username">
<input type="submit">
</form>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
data:{
username:""
},
methods: {
onSubmit(){
if(this.username.length>2){
location.href="http://baidu.com" // 如果验证了输入框内容长度大于2才能跳转至百度
}
},
clickH1(e,event){
console.log(e)
console.log(event)
},
clickBtn(){
alert(123)
},
clickOut(){
console.log("out")
},
clickBox(){
console.log("box")
}
},
})
</script>
23-26行新建一个form表单,并且绑定提交事件,并使用
.prevent
绑定onSubmit
方法- 第24行input输入绑定username变量
- 37-41行新建onSubmit方法,内容是检查username变量的长度
如果输入栏长度不大于2那么就会被.prevent
阻止提交跳转页面。
测试页面:
当输入栏中只有两位长度时,点击提交按钮,会被拒绝跳转。
只有当输入内容大于3时点击提交按钮才会跳转。
2.0例子
除此之外可以使提交按钮在当输入框内容不符合条件时默认为disable状态,不允许点击按钮。
可以在form表单中绑定input事件,然后对应新建myIpt方法,通过新建一个isShow布尔值,来判断提交按钮是否有效。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 @click="clickH1(123,$event)">点击打印传递的参数123</h1>
<h1 @click="clickH1">点击查看原生 DOM 事件</h1>
<button @click.once="clickBtn">按钮</button>
<hr>
<div class="out" @click="clickOut" style="width: 400px;height: 400px;background-color: pink;">
<div class="box" @click.stop="clickBox" style="width: 100px;height: 100px;background: orange;">
box
</div>
</div>
<form @submit.prevent="onSubmit">
<input type="text" v-model="username" @input="myIpt">
<input type="submit" :disabled="isShow">
<h1>{{isShow}}--{{username.length}}</h1>
</form>
</div>
</body>
</html>
<script>
new Vue({
el:"#app",
data:{
username:"",
isShow:true,
},
methods: {
myIpt(){
if(this.username.length>2){
this.isShow=false // 如果验证了输入框内容长度大于2按钮才允许点击
}else{
this.isShow=true
}
},
onSubmit(){
if(this.username.length>2){
location.href="http://www.baidu.com" // 如果验证了输入框内容长度大于2才能跳转至百度
}
},
clickH1(e,event){
console.log(e)
console.log(event)
},
clickBtn(){
alert(123)
},
clickOut(){
console.log("out")
},
clickBox(){
console.log("box")
}
},
})
</script>
23-27行为表单
- 第24行绑定了input事件,并且对应绑定了myIpt方法
- 第25行将disabled属性绑定isShow布尔值
- 39-50行对应绑定的方法
测试页面:
当长度小于等于2时,提交按钮不允许点击。
长度大于2时,提交按钮允许点击。
按键修饰符
可以让标签监听键盘事件,当用户在输入栏中敲入对应的按键时会调用其绑定的方法。
官方文档:https://cn.vuejs.org/v2/guide/events.html#%E6%8C%89%E9%94%AE%E4%BF%AE%E9%A5%B0%E7%AC%A6
此处评论已关闭