一、Vue事件处理
1、Vue.js 提供了事件处理机制,事件监听使用v-on指令监听DOM事件来触发JavaScript代码。
2、通常情况下需要编写监听事件、方法事件处理器等
二、v-on指令与事件监听
1、v-on指令为 HTML 元素绑定事件监听,类似原生JavaScript的onclick等写法,也是在HTML元素上进行监听。
2、表达式 v-on:事件名称 ='函数名称()' 表达式可以是一个方法的名字或一个内联语句,可以简写为 @事件名称 ='函数名称()' 函数定义在methods配置中。
3、事件调用的方法没有参数
<div id="app">
<button @click="btn1Click()">按钮1</button>
<button @click="btn1Click">按钮1</button>
</div>
//写在methods里
methods: {
btn1Click() {
console.log("按钮1");
},
}
点击按钮1时,会在控制台输出按钮1
4、存在参数的方法使用
<button v-on:click="btn1('你好鸭!')">按钮1</button>
//写在methods里
methods: {
btn1: function(msg) {
alert(msg);
}
}
点击按钮1时,会弹出写着“你好鸭!”的弹窗
5、在事件定义时, 写方法时省略了小括号, 如果方法本身有一个参数的, 这个时候, Vue会默认将浏览器生产的原生事件event参数传递到方法
<div id="app">
<button @click="btn2Click">按钮2</button>
</div>
//写在methods里
methods: {
btn2Click(event) {
console.log('按钮2', event);
},
}
点击按钮2时,会在控制台输出按钮2
6、有时也需要在内联语句处理器中访问原始的 DOM 事件。方法定义时, 我们需要event对象, 同时又需要其他参数,在调用方式, 如何手动的获取到浏览器参数的event对象: $event
<div id="app">
<button @click="btn3Click(abc, $event)">按钮3</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
abc: '你好鸭!'
},
methods: {
//写在methods里
btn3Click(abc, event) {
console.log('按钮3', abc, event);
}
}
})
</script>
点击按钮3时,会在控制台输出按钮3 你好鸭!
7、v-on事件处理案例
<!DOCTYPE html>
<html>
<head>
<title>v-on事件处理</title>
<meta charset="utf-8">
<script src="lib/vue.js"></script>
<style>
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
empty-cells: show;
}
tr {
line-height: 30px;
}
tr:nth-child(2n) {
background-color: #efefef;
}
th,
td {
padding: 8px 16px;
text-align: left;
}
th {
background: #cfeef0;
color: #5c6b77;
font-weight: 600;
white-space: nowrap;
}
.totalnum {
margin-top: 10px;
}
</style>
</head>
<body>
<div id="app">
<div>
<table>
<thead>
<tr>
<th></th>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in telList" v-show="item.count!=0">
<td>{{index+1}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<input type="number" name="" style="width: 50px" v-model.number.trim="item.count"><!-- 表单输入框修饰符 -->
<!-- v-on: 事件名称 = "函数名称()" -->
<!-- 简写: @事件名称 = "函数名称()" -->
<button v-on:click="reduce(index)">-</button><!-- 本人理解为这里的index是下标 -->
{{item.count}}
<button @click="add(index)">+</button>
</td>
<td>
<button @click="remove(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<div>
总价:{{toltalprice}}¥
</div>
</div>
</div>
</body>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
telList:[
{
name:"xiaomi12", //这里的数据在渲染的时候,这里的默认下标为0,下标是作为这个数据的唯一标识
price:3600,
count:10
},{
name:"huaweiP50", //这里的默认下标为1
price:7500,
count:5
},{
name:"iphone13", //这里的默认下标为2
price:8900,
count:1
},{
name:"vivoX5", //这里的默认下标为3,以此类推
price:7200,
count:0
}
]
},
methods:{
reduce(index){ //这里的index是下标,如果将index写成1的话,即reduce(1){this.telList[1].count--} 按钮就会写死,只有下标为1的按钮才能将商品数量减少
this.telList[index].count-- //商品数量减少
},
add(index){
this.telList[index].count++ //商品数量增加
},
remove(index){
this.telList.splice(index,1)//删除一行
}
},
computed:{
toltalprice(){
var toltal=0
for(var i=0;i<this.telList.length;i++){
toltal+=this.telList[i].price*this.telList[i].count
}
return toltal
}
}
})
</script>
</html>
三、v-on修饰符
1、v-on后面可以增加修饰符,在@绑定的事件后加小圆点“.”,再跟一个后缀来使用修饰符,Vue中常用的修饰符如下
.stop:调用event.stopPropagation()
.prevent : 调用event.preventDefault()
.self : 只当时间是从侦听器绑定的元素本身触发时才触发回调
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
2、按键修饰符
在监听键盘事件的时候,我们常常需要监测一些常用的键值(keyCode)。为此,Vue 允许为 v-on 在监听键盘事件时添加关键修饰符,以此来接受一个表示 keyCode 的参数并判断。 Vue 提供的一些常用的按键别名为:
.enter 、esc
.delete (捕获 “删除” 和 “退格” 键)
.space
.up 、down
.left、right
.tab
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta
3、v-on绑定键盘事件keyup.enter案例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-on绑定键盘事件keyup.enter</title>
</head>
<body>
<div id="app">
得分:{{count}}
<br>
<input type="text" @keyup.enter="onEnter" v-model="secondCount" placeholder="输入数值按回车加到得分上">
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
count: 0,
secondCount: ''
}
},
methods: {
onEnter() {
// 文本框的数字会默认转成字符串,此处用parseInt()进行整数转换
this.count = this.count + parseInt(this.secondCount);
}
}
});
</script>
</body>
</html>
四、v-model与表单
1、能轻松实现表单输入和应用状态之间的双向绑定,双向绑定指的是我们在vue实例中的data与其渲染的dom元素上的内容保持一致,两者无论谁被改变,另一方也会相应的更新为相同的数据
2、语法:v-model = 变量 v-model 指令只能用在<input>, <select>,<textarea>等这些表单元素上。
3、当用户改变输入框里面的内容时,h1标签渲染出的内容也会改变,两者的内容始终保持一致
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-model与表单</title>
</head>
<body>
<div id="app">
<input type="text" v-model='msg'></input>
<h1>{{msg}}</h1>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
msg: "你好鸭!"
}
}
});
</script>
</body>
</html>
4、v-model指令也有修饰符,用于控制数据同步的时机
修饰符lazy:在输入框中,v-model默认是在input事件中同步输入框的数据,使用修饰符lazy会转变为在change事件中同步。添加lazy修饰符之后,msg并不是实时改变了,而是在失去焦点或者按下回车时才更新
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-model中的lazy修饰符</title>
</head>
<body>
<div id="app">
<input type="text" v-model.lazy='msg'></input>
<h1>{{msg}}</h1>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
msg: "你好鸭!"
}
}
});
</script>
</body>
</html>
修饰符trim:修饰符trim 可以自动过滤输入的首尾空格。如果是密码等输入框,请不要加trim修饰,有些用户可能会用空格做密码。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-model中的trim修饰符</title>
</head>
<body>
<div id="app">
<input type="text" v-model.trim='msg'></input>
<h1>{{msg}}</h1>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
msg: "你好鸭!"
}
}
});
</script>
</body>
</html>
五、v-model与表单综合案例
<!DOCTYPE html>
<html>
<head>
<title>vue模板语法</title>
<meta charset="utf-8">
<script src="lib/vue.js"></script>
<style>
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
empty-cells: show;
}
tr {
line-height: 30px;
}
tr:nth-child(2n) {
background-color: #efefef;
}
th,
td {
padding: 8px 16px;
text-align: left;
}
th {
background: #cfeef0;
color: #5c6b77;
font-weight: 600;
white-space: nowrap;
}
.totalnum {
margin-top: 10px;
}
</style>
</head>
<body>
<div id="app">
<div>
<table>
<thead>
<tr>
<th>序号</th>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- v-for:负责把data中的数组\对象遍历,渲染出来 -->
<tr v-for="(item,index) in telList" v-if="item.telcount!=0" v-bind:key="index">
<td>{{index+1}}</td>
<td>{{item.telname}}</td>
<td>{{item.telprice}}</td>
<td>
<!--
v-model:把用户输入的值绑定到data
-->
<input type="number" name="" style="width: 50px" v-model.number.trim='item.telcount'>
</td>
<td>
<button v-on:click="remove(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<div>
总价:{{totalprice}}¥
</div>
</div>
</div>
</body>
<script type="text/javascript">
var telList=[{
telname:"小米12",
telprice:3600,
telcount:10
},{
telname:"华为P50",
telprice:7600,
telcount:5
},{
telname:"iPhone13",
telprice:8900,
telcount:0
},{
telname:"vivoX5",
telprice:7500,
telcount:5
}]
new Vue({
el:"#app",
data:{
telList,
},
methods:{
remove(index){
this.telList.splice(index,1)
}
},
computed:{
totalprice(){
//总价:
var total=0
for(var i=0;i<this.telList.length;i++){
total+=this.telList[i].telprice*this.telList[i].telcount
}
return total
}
}
})
</script>
</html>