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 }
上面代码的写法是不合理的,因为监听只会触发一次,并不会实现实时监听