watch
watch是侦听时间(以前叫监听)它具备handler默认函数,当监视属性发生变化时,他就会自动调用,类似于coomputed中的getter和setter,在watch中还可以监视多个源,甚至可以监视多级结构中的属性的变化,当需要监视的属性中存在多级结构时,也可以开启深度监视功能来检测属性的变化。watch的调用可以卸载Vue实例中的wacth配置项中,也可以在外边调用¥watch属性来进行设置,如果watch的配置中只有handler函数,也可以将此监视属性进行简写。
<!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>监视属性</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>天气很热{{info}}</h2>
<button @click="changWeather">切换天气</button>
<button @click="isHot = !isHot">切换天气</button>
<hr/>
<h2>{{number.a}}</h2>
<button @click="number.a++">点我a++</button>
<hr/>
<h2>{{number.b}}</h2>
<button @click="number.b++">点我b++</button>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
isHot: true,
number: {
a: 1,
b: 1
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changWeather() {
this.isHot = !this.isHot
}
},
watch: {
//也可以监视计算属性
isHot: {
//hander和computed中的属性一样,当isHot变化是他会自动执行handler函数
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
},
//简写
isHot() {
console.log('isHot被修改了', newValue, oldValue);
},
//检测多级结构中的某个属性的变化
'number.a': {
handler() {
console.log('a被改变了');
}
},
//监视多级结构中的所有属性的变化
number: {
deep: true, //深度监视
handler() {
console.log('number改变了');
}
}
}
})
vm.$watch('isHot', {
//hander和computed中的属性一样,当isHot变化是他会自动执行handler函数
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
})
vm.$watch('isHot', function() {
console.log('isHot被修改了', newValue, oldValue);
})
</script>
</body>
</html>
computed
computed是计算属性,实质是将属性再一次进行加工,内置了getter和setter,其原理是来自于数据代理中的Object.defineProperty(),当计算属性中只有getter时,可以就将其简写成函数的形式,计算属性和methods的区别是自动调用getter函数作为返回值,还会做一次缓存,减少请求次数,但是,当其所依赖的数据发生变化是,就会从新调用getter函数,其中调用函数的时机分为两种:第一个时间调用: 第二个是所依赖的数据发生变化时;
<!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>计算属性</title>
<!-- 计算属性是指在现有的data属性上进行再次加工 -->
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<button @click="show1($event)">点我</button>
<hr/>
<span>姓</span><input type="text" v-model="firstName"><br/><br/>
<span>名</span><input type="text" v-model="lastName"><br/><br/>
<span>全名</span><span>{{fullName}}</span>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
firstName: 1,
lastName: 2
},
methods: {
show1(event) {
console.log(event);
}
},
computed: {
// 完整写法
fullName: {
// 自动调用getter函数作为返回值,还会做一次缓存
// 第一个时间调用:初次调用fullName时 第二个是所依赖的数据发生变化时
get() {
return this.firstName + '-' + this.lastName
},
set(value) {
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
//简写
/* fullName: function() {
return this.firstName + '-' + this.lastName
} */
}
})
</script>
</body>
</html>
区别
watch可以开启异步任务,而且在开启异步任务的同时要是用箭头函数使得this的指向于Vue实例对象(因为settimeout、ajax都是由js引擎管理的,但是箭头函数是没有this指向的,谁调用箭头函数,this指向谁,由此开启任务时,this指向调用者Vue实例),而在操作Vue实例中的对象是要写成普通函数的样子。computed所依赖的时函数return值,所以对于计算属性来说并不能设置异步任务。
<!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="root">
<span>姓:</span><input type="text" v-model="firstName"><br/><br/>
<span>名:</span><input type="text" v-model="lastName"><br/><br/>
<span>全名computed:</span><span>{{fullName}}</span>
<span>全名watch:</span><span>{{fullName1}}</span>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
firstName: 1,
lastName: 2,
fullName1: '1 - 2',
},
computed: {
//计算属性不能开启异步任务,他依靠的是return的返回值
//完整写法
fullName: {
// 自动调用getter函数作为返回值,还会做一次缓存
// 第一个时间调用:初次调用fullName时 第二个是所依赖的数据发生变化时
get() {
return this.firstName + '-' + this.lastName
},
set(value) {
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
//简写
/* fullName: function() {
return this.firstName + '-' + this.lastName
} */
},
watch: {
//watch可以开启异步任务
firstName(newValue) {
setTimeout(() => {
this.fullName1 = newValue + '-' + this.lastName;
}, 1000);
},
lastName(newValue) {
this.fullName1 = this.firstName + '-' + newValue;
}
}
})
</script>
</body>
</html>