watch监听

在vue中,使用watch来响应数据的变化

下面我们看一个案例

 1 <template>
 2   <div>
 3    <p>{{num}}</p> 
 4     <button @click="add">加一</button>
 5   </div>
 6 </template>
 7 
 8 <script>
 9   export default {
10     data(){
11       return {
12         num:0
13       }
14     },
15     methods:{
16       add(){
17         this.num++
18       }
19     },
20     watch:{
21       num(newVal,oldVal){
22         console.log(newVal,"新数据")
23         console.log(oldVal,"旧数据")
24 
25       }
26     }
27   }
28 </script>
29 
30 <style lang="scss" scoped>
31 
32 </style>

watch的基本使用是传出两个参数,一个是旧的数据,一个是新的数据

 

 

 

watch 的作用是用来监听数据的,主要监听的数据有data中的数据、props、路由

我们看一个小案例

 1 <template>
 2   <div>
 3    <p>{{num}}</p> 
 4     <p>  
 5     {{type}}  //type的值是根据watch监听到的num实时返回的    
 6     </p>
 7     <button @click="add">加一</button>
 8   </div>
 9 </template>
10 
11 <script>
12   export default {
13     data(){
14       return {
15         num:0,
16         type:"偶数"
17       }
18     },
19     methods:{
20       add(){
21         this.num++
22       }
23     },
24     watch:{
25       num(newVal){
26         // 根据当前的num数值去判断当前数字的奇偶性,从而改变type类型
27         this.type = newVal % 2 == 0 ? "偶数" : "奇数"
28       }
29     }
30   }
31 </script>
32 <style lang="scss" scoped>
33 </style>

 

 

 

 我们再看以案例,如果data中返回的数据是一个对象会怎么样

 1 <template>
 2   <div>
 3    <p>姓名{{obj.name}}</p> 
 4     <p>  
 5    年龄 {{obj.age}}
 6     </p>
 7     <button @click="add">加一</button>
 8   </div>
 9 </template>
10 
11 <script>
12   export default {
13     data(){
14       return {
15       obj:{
16         name:"小明",
17         age:18
18       }
19       }
20     },
21     methods:{
22       add(){
23         this.obj.age++
24       }
25     },
26     watch:{
27       obj(newVal){
28         console.log(newVal)
29       }
30     }
31   }
32 </script>
33 <style lang="scss" scoped>
34 </style>

此时会发现,数据会发生改变,但是控制台不会输出结果

 

 

此时我们需要把watch中obj改为obj.age即可

1 watch:{
2       "obj.age"(newVal){
3 
4         console.log(newVal)
5       }
6     }

 

 此时就可以实现输出

原因:为什么会改变值而没有输出,是因为没有监听到吗,并不是,而是监听到了,只是不支持对象、复杂类型的最外层包裹,它只能监听属性不能监听当前复杂类型的对象,所以改为obj.age就可以输出结果。

 

如果我们需要页面初始化的时候就能触发一次监听,必须要使用handler函数方式

我们看下面的一个案例

 1 <template>
 2   <div>
 3    <p>姓名{{obj.name}}</p> 
 4     <p>  
 5    年龄 {{obj.age}}
 6     </p>
 7     <button @click="add">加一</button>
 8     <p>
 9     状态:{{state}}
10     </p>
11   </div>
12 </template>
13 
14 <script>
15   export default {
16     data(){
17       return {
18       obj:{
19         name:"小明",
20         age:16
21       },
22        state:""
23       }  
24     },
25     methods:{
26       add(){
27         this.obj.age++
28       }
29     },
30     watch:{
31      'obj.age':{
32        handler(val){
33         this.state = val >= 18 ? '已成年' : '未成年'
34        },
35        immediate:true      //是否初始化时进行监听
36      }
37     }
38   }
39 </script>
40 <style lang="scss" scoped>
41 </style>

此时打开页面就会显示,当我们点击加一之后

 

 

handler是监听函数,如果需要初始化时候进行监听,将immediate设置为 true

需要注意的是复杂类型只只支持监听属性值,或者对象值,不支持监听整个数据类型

1 watch:{
2   obj:{
3     handler(val) {
4       this.state = val >= 18 ? '已成年' : '未成年'
5     },
6     immediate:true
7   }
8 }

上面代码的写法是不合理的,因为监听只会触发一次,并不会实现实时监听

 

posted @ 2021-09-15 14:58  keyeking  阅读(661)  评论(0编辑  收藏  举报