目录
第二章
一、事件机制
1.1概述
在dom阶段,我们已经讲述了事件机制的特点:
- 事件三要素
- 事件绑定
- 事件流
- 事件对象
- 事件代理
- 事件类型
这些概念在vue中依旧存在,但是vue中的事件机制要更加的简单便捷⼀些
1.2.Vue中的事件机制
在前端开发中,我们需要经常交互。
这个时候,我们就必须监听交互的发⽣,⽐如点击、拖拽、键盘事件等等
在Vue中如何监听事件呢?使⽤v-on指令
v-on介绍
- 作⽤:绑定事件监听器
- 缩写:@ 预期:Function | Inline Statement | Object
- 参数:event
这⾥,我们⽤⼀个监听按钮的点击事件,来简单看看v-on的使⽤
下⾯的代码中,我们使⽤了v-on:click=“counter--”,可以直接在后⾯写⼊表达式
另外,我们可以将事件指向⼀个在methods中定义的函数
<div id="app">
<button v-on:click="counter--">点击按钮1</button>
<button v-on:click="btnClick">点击按钮2</button>
</div>
methods: {
btnClick(){
this.counter++
}
}
<!-- v-on也有对应的语法糖: v-on:click可以写成@click -->
<button @click="btnClick">点击按钮2</button>
1.3.v-on参数传递
当通过methods中定义⽅法,以供@click调⽤时,需要注意参数问题:
情况⼀:如果该⽅法不需要额外参数,那么⽅法后的()可以不添加。
但是注意:如果⽅法本身中有⼀个参数,那么会默认将原⽣事件event参数传递进去
<button @click="handleAdd">点击按钮1</button>
handleAdd(event){
console.log(event);
}
情况⼆:如果需要同时传⼊某个参数,同时需要event时,可以通过$event传⼊事件
<button @click="handleAddTen(10, $event)">点击按钮2</button>
handleAddTen(count, event){
console.log(count, event);
}
1.4.v-on的事件修饰符
在事件处理程序中调⽤ event.preventDefault() 或 event.stopPropagation() 是⾮常常⻅的 需求。Vue提供了更好的⽅ 式:事件处理函数只有纯粹的数据逻辑,⽽不是去处理 DOM 事件细节,通过事件修饰符来完成这些细节。
常⻅修饰符如下
.stop
停⽌事件冒泡,相当于调⽤event.stopPropagation()
<button @click.stop="doThis">停⽌冒泡</button>
.prevent
⽌事件默认⾏为,相当于调⽤ event.preventDefault()
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form
.once
事件处理函数执⾏⼀次后解绑
<button @click.once="doThis"></button
.{keyCode | keyAlias}
只当事件是从特定键触发时才触发回调
<input @keyup.enter="doThis">
按键修饰符
⼀般与keyup事件类型配合使⽤
.enter、.tab、.delete、.esc、.space、.up、.down、.left、.right .ctrl、.alt、.shift、.meta
⿏标修饰符 .left、.right、.middle
二、表单输入绑定
⽤v-model指令在表单
<input type="text" v-model="message">
<h2>输⼊的值是:{{message}}</h2>
data: {
message: ''
}
以上代码的解析:
当我们在输⼊框输⼊内容时 因为input中的v-model绑定了message,所以会实时将输⼊的内容传递给message,message发⽣改变。 当 message发⽣改变时,因为上⾯我们使⽤Mustache语法,将message的值插⼊到DOM中,所以DOM会发⽣ 响应的改变。 所以,通过v-model实现了双向的绑定。
v-model与表单元素结合使⽤
1. 单⾏⽂本框
<input v-model="message" placeholder="edit me">
2. 多⾏⽂本框
<textarea v-model="message" placeholder="multiple lines"></textarea> 3. 单选按钮
<input type="radio" value="One" v-model="picked">
<input type=“radio” value="Two" v-model="picked">
4. 复选按钮
<input type="checkbox" value="Jack" v-model="checkedNames">
<input type="checkbox" value="John" v-model="checkedNames">
5. 下拉菜单
<select v-model="selected">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
2.1.v-model修饰符
使⽤修饰符可以增加表单绑定能⼒
.lazy
默认情况下,v-model 在每次 input 事件触发后将输⼊框的值与数据进⾏同步。可以添加 lazy 修饰符,从 ⽽转为在 change 事件之后进⾏同步
<!-- 在“change”时⽽⾮“input”时更新 -->
<input v-model.lazy="msg">
.number
如果想⾃动将⽤户的输⼊值转为数值类型,可以给 v-model 添加 number 修饰符
<input v-model.number="age" type="number">
.trim
如果要⾃动过滤⽤户输⼊的⾸尾空⽩字符,可以给 v-model 添加 trim 修饰符
<input v-model.trim="msg">
三.计算属性
我们知道,在模板中可以直接通过插值语法显示⼀些data中的数据。
但是在某些情况,我们可能需要对数据进⾏⼀些转化或计算后再显示,或者需要将多个数据结合起来进⾏显示
- ⽐如我们有firstName和lastName两个变量,我们需要显示完整的名称
- 但是如果多个地⽅都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}
我们可以将上⾯的代码换成计算属性:
<h2>{{fullName}}</h2>
computed: {
fullName(){
return this.firstName + ' ' + this.lastName
}
}
我们可能会考虑这样的⼀个问题:
methods和computed看起来都可以实现我们的功能,
那么为什么还要多⼀个计算属性这个东⻄呢?
原因:计算属性会进⾏缓存,如果多次使⽤时,计算属性只会调⽤⼀次
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 以前 -->
<h2>{{firstName}}{{lastName}}</h2>
<!-- ⽤methods -->
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<!-- 计算属性 -->
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{arrayFilter}}</h2>
</div>
<script src="./js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName: 'Lebron',
lastName: 'James'
},
methods: {
getFullName(){
console.log('-----methods-----fullName');
return this.firstName + ' ' + this.lastName
}
},
// 计算属性 ⽤来处理⼀些需要转换 计算 多个复杂数据融合的
computed: {
fullName(){
console.log('-----computed-----fullName');
return this.firstName + ' ' + this.lastName
},
// 数组筛选
arrayFilter(){
let arr = [1,2,3,4,5,6,7]
// 筛选出⼤于2的数据
return arr.filter(function (item) {
return item > 2
})
}
},
})
</script>
</body>
</html
四.侦听器
侦听器的应用场景
- 使⽤watch来响应数据的变化
- ⼀般⽤于异步或者开销较⼤的操作
- watch中的属性 ⼀定是data中已经存在的数据
4.1侦听器的基本使用
data: {
testData: ‘testData’
},
// 使⽤侦听器来监听testData的变化
watch: {
// 侦听数据的变化 函数名要和data中定义的属性名保持⼀致
// 我们给其定义⼀个形参val 表示的是testData当前更新后最新的值 只要数据发⽣变化 val就会跟着变
化 就会得到最新的值
testData(val){
//val就是testData更新后拿到的最新的值
console.log(val);
}}
侦听器在使⽤层⾯上与计算属性类似,但是 有⼀些场景计算属性是实现不了的 异步或者开销较⼤的操作的时候
案例1:侦听器的基本使⽤
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
名:<input type="text" v-model="firstName">
姓:<input type="text" v-model="lastName">
<h2>全名:{{fullName}}</h2>
<h2>全名:{{fullName2}}</h2>
</div>
<script src="./js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName: 'Lebron',
lastName: 'James',
fullName: 'Lebron James'
},
// 使⽤侦听器
// 侦听器⽤来监听data中定义的属性的变化
watch: {
// 侦听数据的变化 函数名要和data中定义的属性名保持⼀致
// 我们给其定义⼀个形参val 表示的是firstName当前更新后最新的值 只要数据发⽣变化 val就会
跟着变 化 就会得到最新的值
firstName(val){
console.log('事件触发', val);
// 拼接
this.fullName = val + ' ' + this.lastName
},
lastName(val){
this.fullName = this.firstName + ' ' + val
}
},
computed: {
fullName2(){
return this.firstName + ' ' + this.lastName
}
},
})
</script>
</body>
</html>
案例2:侦听器的模拟异步操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 需求 验证⽤户名 如果⽤户名重名 提示 当前⽤户名已存在,请更换! 如果不重复 提示 可以使⽤ -->
<div id="app">
请输⼊⽤户名:<input type="text" v-model.lazy="username">
{{tip}}
</div>
<script src="./js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
username: '',
tip: ''
},
// 侦听器
watch: {
username(val){
this.tip = '正在验证...'
// 使⽤延时函数模拟异步操作
setTimeout(() => {
if (val == 'admin') {
this.tip = '当前⽤户名已存在,请更换⽤户名!'
}else{
this.tip = '当前⽤户名可以使⽤!'
}
}, 2000);
}
},
})
</script>
</body>
</html>