本文已参与「新人创作礼」活动,一起开启掘金创作之路。
目录
watch:在vue中,使用watch来响应数据的变化,监听异步操作异步场景。
{{watchFullName}}无需加()
案例只监听了data中数据的watchFullName的变化
<!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="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<!-- watch监听异步操作异步场景监听器后面无需加()
此案例只监听了data中数据的watchFullName的变化
-->
<div id="box">
<h1>计算属性:computed</h1>
{{fullName}}
<h1>方法:methods</h1>
{{fullName2()}}
<h1>监听器:watch</h1>
{{watchFullName}}
<h1>年龄</h1>
{{age}}
</div>
<script>
var other = 'This is other';
var box = new Vue({
el:'#box',
data:{
firstName:'Nan',
lastName:'Chen',
age:18,
watchFullName:'NanChen',
},
methods: {
fullName2:function(){
console.log("调用了fullName,执行了一次方法")
fullName2 = this.firstName+this.lastName+","+other;
return fullName2;
}
},
computed: {
fullName:function(){
console.log("调用了fullName,计算了一次属性")
return this.firstName+this.lastName+","+other;
}
},
watch:{
immediate: true,
firstName:function(newName,oldName){
console.log("lastName触发了watch,newLastName="+newName+",oldLastName="+oldName);
this.watchFullName = this.firstName+this.lastName+","+other;
},
lastName:function(newName, oldName){
console.log("lastName触发了watch,newLastName="+newName+",oldLastName="+oldName)
this.watchFullName = this.firstName+this.lastName+","+other
} ,
}
})
</script>
</body>
</html>
这样使用watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。
那如何去修改年龄(age) 呢?
可以直接在控制台写
box.age=80
这里的方法需要重新执行,而watch中没有age属性所以不用在执行一遍
如何更改other的值?
因为不是box中的元素所以可以直接写other
这里没有发生任何变化再次修改firstName就会进行重新渲染
原因:是因为我们调用firstName的时候触发了所有的方法包括更改后的watch,上面已经改为了新的值,所以也会跟着改。在实例外的对象,它并不是一修改就有的。而是在修改之后再次修改实例内置对象,它才会更改。
结论:
- 使用computed计算了fullName属性,值为firstName+lastName。
- 计算属性具有
缓存功能,当firstName和lastName都不改变的时候,fullName不会重新计算,比如我们改变age的值,fullName的值是不需要重新计算的。 - methods并没有缓存特性,比如我们改变age的值,fullName2()方法会被执行一遍。
- 当一个功能可以用上面三个方法来实现的时候,明显使用computed更合适,代码简单也有缓存特性。
- 计算属性范围在vue实例内,修改vue实例外部对象,不会重新计算渲染,但是如果先修改了vue实例外对象,在修改vue计算属性的对象,那么外部对象的值也会重新渲染。
computed和watch
**computed: **计算属性范围在Vue实例的fullName内所管理的firstName和lastName,通常监听多个变量
watch: 监听数据变化,一般只监听一个变量或数组
使用watch深度监听01
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p>FullName: {{person.fullname}}</p>
<p>FirstName: <input type="text" v-model="person.firstname"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data() {
return {
person: {
firstname: 'Menghui',
lastname: 'Jin',
fullname: ''
}
}
},
methods: {
},
computed: {
person2(){
return JSON.parse(JSON.stringify(this.person));
}//解决深度监听新老值同源问题
},
watch:{
person2:{
handler(n,o){
console.log(this.person);
console.log(n.firstname);
console.log(o.firstname);
/* this.person.fullname = this.person.firstname + this.person.lastname */
},
/* immediate: true, */
deep: true // 可以深度检测到 person 对象的属性值的变化
}
}
})
</script>
</body>
</html>
watch深度监听02
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h2>{{sum}}</h2>
<button @click="sum++">点击</button>
<p>FullName: {{person.fullname}}</p>
<p>FirstName: <input type="text" v-model="person.firstname"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data() {
return {
sum:0,
person: {
firstname: 'Menghui',
lastname: 'Jin',
fullname: ''
}
}
},
methods: {
},
computed: {
person2(){
return JSON.parse(JSON.stringify(this.person));
}//解决深度监听新老值同源问题
},
watch:{
person2:{
handler(n,o){
console.log(this.person);
console.log(n.firstname);
console.log(o.firstname);
/* this.person.fullname = this.person.firstname + this.person.lastname */
},
/* immediate: true, */
deep: true // 可以深度检测到 person 对象的属性值的变化
},
sum:{
handler(n,o){
console.log('sum的值变化了',n,o);
}
}
}
})
</script>
</body>
</html>
\