目录
[3.参数 event](#3.参数 event)
[1.阻止默认事件 常用](#1.阻止默认事件 常用)
[2.阻止事件冒泡 常用](#2.阻止事件冒泡 常用)
[3.事件只触发一次 常用](#3.事件只触发一次 常用)
[(二)方法实现 姓名案例](#(二)方法实现 姓名案例)
[(三)计算属性实现 姓名案例](#(三)计算属性实现 姓名案例)
[(二)天气案例 无监听](#(二)天气案例 无监听)
一、事件处理
(一)基本语法
事件的基本绑定是
v-on:加绑定方式 = '回调函数名'
@加绑定方式 = '回调函数名'
(二)点击事件语法
1.事件绑定
点击事件绑定 v-on:click = '回调函数名'
html
<button v-on:click="showInfo">点我提示信息</button>
v-on: 可以简化成@ @click = '回调函数名' 也是一个意思
html
<button @click="showInfo">点我提示信息</button>
2.回调函数
绑定事件的回调函数要写在 Vue 实例的 methods 对象中 如下
showInfo() 函数中的 this 指向 Vue 实例对象
写在 Vue 实例中的函数 尽量用普通函数书写 不然用箭头函数 this 会指向 window
javascript
new Vue({
el: '#root',
data: {
name: '一个人'
},
methods:{
showInfo(event){
alert('你好')
}
}
})
3.参数 event
函数中有个参数是 event 它是被监听的对象 event.target 能找到被我们监听的 button
event.target.innerText 能获得里面的文字内容
注意如果要传参记得给 event 占位 因为 event 很重要 ,在 Vue 模板中 使用 $event 占位
javascript
methods: {
showInfo(event,number) {
console.log(number)
},
想要 event 是第几个参数 就把 $event 写在哪儿就行
html
<button v-on:click="showInfo($event,23)">点我提示信息</button>
注意:
不能把事件处理的回调函数写在 data 中 虽然 也能使用 但是放在 data 中 Vue 会给这个函数默认进行数据代理,但是我们函数不需要修改,只是被调用,不需要数据代理,这样就会加大 Vue 的负担,所以我们单独写在 methods 对象中,methods 中都i是被 Vue 所管理的函数。
(三)事件修饰符
就是来修饰事件的行为的,重点是前三个,可以连着使用类似于 @click.stop.prevent 先停止冒泡再停止默认行为,是有顺序的。
1.阻止默认事件 常用
e.preventDefault() 我们也可以不用这种写法
javascript
methods: {
showInfo1(e) {
e.preventDefault()
alert('同学你好')
}
}
我们可以用下面这种形式 在点击事件 @click 后面加上 事件修饰符 prevent 就是上面阻止默认行为的作用
javascript
<a href="http://baidu.com" @click.prevent="showInfo1">点我提示信息</a>
2.阻止事件冒泡 常用
stop
使用下面的代码,点击里面的按钮会触发两次提示弹窗这是典型的事件冒泡,点击儿子冒泡给父亲
html
<div class="demo" @click="showInfo1">
<button @click.stop="showInfo1">点击</button>
</div>
3.事件只触发一次 常用
once
html
<button @click.once="showInfo1">点击</button>
4.使用事件的捕获模式
capture 要加在外面的盒子 点击里面的盒子 就不会冒泡了
先由外向内捕获 再由内向外冒泡 一般是冒泡阶段输出结果
如果想捕获阶段输出结果
html
<div class="box1" @click.capture="showInfo1">
<div class="box2" @click="showInfo1">点击</div>
</div>
5.当前操作元素触发事件
self
只有event.target 是当前的操作的元素才触发事件
就是点击按钮时 event.target 就是这个 button 不会向上冒泡执行操作了
html
<div class="box1" @click.self="showInfo1">
<div class="box2" @click="showInfo1">点击</div>
</div>
6.事件默认立即执行
passive
移动端用的比较多
也不是所有的事件都需要
滚轮事件需要
不用等滚轮事件的回调结束再触发事件,不然默认是执行完回调函数再去执行事件,如果回调函数执行时间长的话,滚动条就不动了,还会造成页面卡顿
@scroll 滚动条滚动
@wheel 鼠标滚轮滚动
html
<ul @scroll.passive="demo">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
(四)键盘事件语法
1.事件绑定
@keyup @keydown 键盘按键上升时触发 键盘下降时触发
placeholder 默认浅色文字
通过键盘名绑定:
如果像我们按指定按键才能触发相关事件时,我们可以在绑定时指定一个按键别名:
例如 @keyup.enter=''
回车:enter
删除:delete
退出:esc
空格:space
换行:tab (特殊必须配合keydown 使用 因为 tab 本来的用处就能捕获焦点)
上:up
下:down
左:left
右:right
系统修饰键
用 keyup 时按下修饰键同时也得按上其它键,然后释放其它键,事件才能被触发,具体用哪个键子就直接在后面点上就行 比如想 ctrl + y 生效 就写成 @keyup.ctrl.y 的格式
用 keydown 时正常触发事件,按下就触发
ctrl:
alt:
shift:
meta:就是 win 键
html
<input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo">
通过按键的编码绑定
就是 e.keycode 属性 但是不建议使用
html
<input type="text" placeholder="按下回车提示输入" @keyup.13="showInfo">
自定义按键名:
我们也可以自定义按键的名字,前面是自己的名字 然后后面是对应的 按键码 进行绑定,但是也不推荐使用
javascript
Vue.config.keyCodes.huiche = 13
2.回调函数
返回键盘输入的内容 e.target.value 是输入的内容
e.key 是按键的名字 e.keyCode 是按键的编码号
javascript
methods: {
showInfo(e) {
console.log(e.target.value)
}
二、计算属性
(一)简介
首先得明白属性是指什么 Vue 认为属性就是 实例中 data 对象中写的东西
计算属性就是拿着我们 data 中有的属性进行加工和计算 生成一个全新的属性 就是计算属性
计算属性不放在 data 里面 要单独放在 computed 对象中 就是计算的意思
计算属性也属于 Vue 实例 vm 可以直接调用
原理:
使用了 Object.defineproperty 方法提供的 getter 和 setter
javascript
computed:{
fullName:{
get(){
}
}
}
(二)方法实现 姓名案例
1.流程
data 中的数据任何一个发生变化,Vue 模板都会重新解析一遍,如果遇到插值语法中的方法一定会重新调用一遍。所以下面当在页面的文本框中更改姓和名时 使用v-model 指令等于同时也改变了 实例中 data 的值,data 值发生了变化 fullName 函数重新调用 就会发生更改
如果重复调用好几次相同的方法 这个方法就得被调用好几次,模板也会再同样解析好几次
2.代码部分
html
<body>
<div id="root">
性:<input type="text" v-model:value="firstName"> <br>
名:<input type="text" v-model:value="lastName"> <br>
姓名:<span>{{fullName()}}</span>
</div>
<script>
Vue.config.keyCodes.huiche = 13
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三'
},
methods: {
fullName() {
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
(三)计算属性实现 姓名案例
1.流程
我们通过姓和名 两个属性相加得出 姓名 新得到的姓名属性就是计算属性
计算属性也属于 Vue 实例 vm 可以直接调用
因为获得的姓名的过程可能很复杂 我们把姓名以象形式存下,使用 get 方法,当有人读取fullName 时,就调用 get 方法,把 return 里面的值作为 fullName 的值,我们在 return 里面进行拼接字符串就行了
2.特点
实现了缓存的效果
在 get 所依赖的数据没发生变化时,只会读取第一次的姓名然后缓存起来,不会再读取姓名了
但是如果 get 依赖的数据发生变化了就会重新读取更新 然后存缓存
3.注意
在 data 中的性和名不能直接使用 因为存在于不同的作用域,但是 Vue 默认将 get() 方法里面的 this 指向了 Vue 实例 ,我们就能用 this 调用 data 中的数据了。
fullName 不要看成一个对象 不能 fullName.get() 这样会报错,他的内部会自动调用 get 方法把返回值给 fullName 所以直接调用 fullName 就行
如果要改变 fullName 的值然后分别改变姓和名 就得再使用一个 set 方法 ,改变它所依赖的属性
如下:
javascript
set(value){
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
4.代码部分
html
<body>
<div id="root">
性:<input type="text" v-model:value="firstName"> <br>
名:<input type="text" v-model:value="lastName"> <br>
姓名:<span>{{fullName}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三'
},
computed:{
fullName:{
get(){
return this.firstName + '-' + this.lastName
}
}
}
})
</script>
</body>
(四)简写方式
如果只用 getter 的话,只考虑读取不修改,就不用把计算属性写成对象的方式,直接写成函数的形式就行,里面还是 get 方法的写法
调用时它不能看作函数而是一个属性 不能fullName() 直接不加小括号就可以
javascript
computed: {
fullName: function () {
return this.firstName + '-' + this.lastName
}
}
三、监视属性
(一)介绍
监视属性就是监视某一个属性的变化
语法:
watch:{
监视对象:{
hander(){
监视对象改变时喊的人函数被调用
}
}
}
javascript
watch: {
isHot: {
handler(){
}
}
(二)天气案例 无监听
1.流程
点击按钮切换天气
也可以不写changeWeather 方法在 methods 中可以直接 在@click 后面写上 isHot = !isHot
绑定事件后面能写一些简单的语句 但是复杂一点点属性最好还是写在 methods 里面
2.代码部分
html
<body>
<div id="root">
<h2>今天天气预报:{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
<script>
new Vue({
el: '#root',
data: {
isHot: true
},
computed: {
info(){
return this.isHot ? '炎热' : '凉快'
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot
}
}
})
</script>
</body>
(二)监视
1.设置监视
得用一个对象 watch里面 放全新的配置对象,我们想监视 isHot 属性的变化,就用 handler 函数,当isHot 属性变化时会被调用,我们可以通过里面两个参数拿到变化前后的值
newValue,oldValue 新的值,旧的值
isHot 配置对象除了 handler 函数还有 其它配置
immediate;true 没变化就执行 handler 函数
javascript
watch: {
isHot: {
immediate:true,
handler(newValue,oldValue){
console.log('isHot被修改了', newValue, oldValue)
}
}
}
2.其它写法
写在 vm 实例外面不明确监视谁就用下面的形式
javascript
vm.$watch('isHot', {
immediate: true,
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue)
}
})
(三)深度监视
vue是能检测到里面任何层级数据的变化的,检测不到 只是对我们程序员使用 watch 来检测检测不到,默认只监测最外层(为了效率),我们能通过修改默认值 deep 就能实现深度监测
data 中有一个对象类型的数据 如果想要检测里面a,b 的变化从而做出某些反应,不能简单的在watch 里面加上
numbers:{
handler(){
}
}
因为 Vue 认为 numbers 是一个整体这样观测到的只是 numbers 属性的地址,对里面的数据不感兴趣,ab发生变化,vue 会认为 numbers 没有发生变化,不会调用 handler 函数
我们可以使用
'numbers.a':{
handler(){}
}
这样的方式来指定检测变化的变量,但是要是想监测里面所有的变量就得写很多,很浪费空间
javascript
data: {
numbers: {
a: 1,
b: 2
}
},
这时我们就能使用一个属性来轻松解决,检测的对象还是 numbers 但是在里面加上一个属性
这个属性能实现深度监视,deep:true
就是 deep 默认是关闭的 如果打开就能观测到多层级的数据的变化,
javascript
watch: {
numbers: {
deep: true,
handler() {
console.log('number改变了')
}
}
}
(四)监视的简写形式
不需要其它配置项时使用,就可以默认为只有handler 省略名字,直接坚持者写成函数的格式,和计算属性类似,简写不能加其它配置项,deep immediate
javascript
watch: {
isHot(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue)
}
写在 Vue 实例外面的形式:
javascript
vm.$watch('isHot', function(){
console.log('isHot被修改了',newValue,oldValue)
})
四、计算属性监视属性对比
(一)案例对比
用计算属性在实现一些功能时更加简短和方便,但是计算属性不能处理异步的操作,比如说延时输出,这时就得用到监视属性,加一个定时器就行,而计算属性依赖返回值 return 输出,不能加定时器。而且定时器使用必须用箭头函数。
下面这段代码无法输出正常结果
javascript
computed: {
fullName: function () {
setTimeout(() => {
return this.firstName + '-' + this.lastName
}, 1000)
}
}
下面代码能延时 1秒 正常输出结果
javascript
watch: {
firstName(now, last) {
this.fullName = now + this.lastName
},
lastName(now, last) {
setTimeout(() => {
this.fullName = this.firstName + now
}, 1000)
}
}
(二)总结
计算属性computed 能完成的 监视属性 watch 也能完成
监视属性 watch 能完成的任务 计算属性computed 不一定能完成 : 异步任务
所有被 Vue 实例所管理的函数最好写成普通函数这样this 才能指向 vm,有利于后来组件实例对象的学习
所有不被 Vue 所管理的函数 定时器的回调函数,ajax 的回调函数 promise 的回调函数 最好写成箭头函数 这样 this 指向的才是 vm 或是实例对象