事件侦听函数
watch
选项期望接受一个对象,其中键是需要侦听的响应式组件实例属性(例如,通过 data 或 computed
声明的属性)——值是相应的回调函数。该回调函数接受被侦听源的新值和旧值。
除了一个根级属性,键名也可以是一个简单的由点分隔的路径,例如 a.b.c。注意,这种用法不支持复杂表达式——仅支持由点分隔的路径。如果你需要侦听复杂的数据源,可以使用命令式的 $watch() API。
值也可以是一个方法名称的字符串 (通过 methods 声明),或包含额外选项的对象。当使用对象语法时,回调函数应被声明在 handler 中。额外的选项包含:
immediate:在侦听器创建时立即触发回调。第一次调用时,旧值将为 undefined。
deep:如果源是对象或数组,则强制深度遍历源,以便在深度变更时触发回调。详见深层侦听器。
flush:调整回调的刷新时机。详见回调的触发时机。
onTrack / onTrigger:调试侦听器的依赖关系。详见侦听器调试。
声明侦听器回调时避免使用箭头函数,因为它们将无法通过 this 访问组件实例。
<!DOCTYPE html>
<html lang="zh-CN">
<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>侦听函数</title>
<link rel="shortcut icon" href="phone.ico" type="image/x-icon" />
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="root">
姓: <input type="text" v-model='firstName'>
名: <input type="text" v-model='lastName'>
<!-- <span>{{fistName+"-"+lastName}}</span> -->
<span>{{fullName}}</span>
<!-- 如果是fullName的话,就是返回了fullName的函数体,
fullName()则是返回了函数的返回值 -->
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data: {
firstName: 'Feng',
lastName: 'Jialin',
fullName: 'Feng-Jialin'
},
// methods: {
// // methods中的this指针,指向vue实例模型vm
// fullName() {
// return this.fistName + "*" + this.lastName
// }
// },
watch: {
// 使用watch函数侦听firstName的变化,传递参数是新值value
firstName(val) {
// 倘若要进行异步的操作,使用侦听函数会比使用计算属性
// 要适用,计算属性无法进行异步的操作
setTimeout(() => {
this.fullName = val + '-' + this.lastName
}, 1000)
},
lastName(val) {
this.fullName = this.firstName + '-' + val
}
}
})
</script>
</html>
重点解析:
对于箭头函数和普通函数的解析:
(1)箭头函数和普通函数的区别:箭头函数不会产生自己的this,它只会从自己的作用域链的上一层继承 this。
(2)被vue所管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
(3)普通函数中的this代表它的直接调用者, 例如 obj.cal() ,那么cal()方法中的this就是obj,而如果没找到直接调用者,则this指的是 window。
(4)在本篇的博客之中,出现的setTimeout函数,我们则是直接使用了箭头函数,这与第二条,vue所管理的函数最好写成普通函数并不冲突。原因是在于,定时器函数的执行是JS引擎触发,当采用箭头函数时,因为它自己没有this,就会去找上一级的this对象,找到firstName的this,firstName的形式是普通函数的形式,我们知道普通函数的this是它的直接调用者,进而找到vm对象。可是当如果采用function普通函数形式时,就会直接是调用的window对象。
(5)不被vue所管理的函数,比如:定时器的回调函数
、ajax的回调函数
、Promise的回调函数
,最好写成箭头函数,这样的this指向才是vm或组件实例对象。
箭头函数的外层如果有普通函数,那么箭头函数的this就是这个外层的普通函数的this,箭头函数的外层如果没有普通函数,那么箭头函数的this就是全局变量。
下面这个例子是箭头函数的外层有普通函数。
let obj = {
fn:function(){
console.log('我是普通函数',this === obj) // true
return ()=>{
console.log('我是箭头函数',this === obj) // true
}
}
}
console.log(obj.fn()())
let obj = {
fn:()=>{
console.log(this === window);
}
}
console.log(obj.fn())
// true