1.监视属性

监视属性:监视某个属性的变化

小案例:

<!DOCTYPE html>
<html lang="en">
<body>
   
    <div id="root">
      <h2>今天天气很{{hot?'热':'冷'}}</h2>
      <button @click="changeWeather">切换天气</button>
    </div>   
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                hot:true,  //布尔值
            },
            methods:{
                changeWeather(){
                    this.hot=!this.hot
                }
            }
        })
    </script>
</body>
</html>

如果我们把其中的一行代码改成

      <h2>今天天气很一般</h2>

这个时候我们去点击按钮,页面上的数据不会改变,但是data里面的hot已经改变了,这有什么问题呢,其实这是个小坑,因为vue觉得你这个值没有在页面上展示,所以没有必要体现出来,如果你后面要用到这个值就会出现问题。

(PS:最新版已经修复了这个问题,如果你还是用 旧版本需要注意这个问题)

监视属性的由来?

可以看出我们需要的就是某个值改变了然后通知我们即可,这个 时候就用到了 监视属性watch了

简单写法如下:

 //监视属性
            watch: {
                //需要监视的值
                hot: {
                    //handler什么时候调用?当hot发生改变时调用
                    handler() {
                        console.log("hot值被修改了")
                    }
                }

            }

其中handler里面有两个参数,一个是新的值newValue,一个是旧的值oldValue。整体代码如下:

<!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>vue测试</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>今天天气很{{hot?'热':'冷'}}</h2>
        <button @click="changeWeather">切换天气</button>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                hot: true,  //布尔值
            },

            methods: {
                changeWeather() {
                    this.hot = !this.hot
                }
            },
            //监视属性
            watch: {
                //需要监视的值
                hot: {
                    //handler什么时候调用?当hot发生改变时调用
                    handler(newValue,oldValue) {
                        console.log("hot值被修改了",newValue,oldValue)
                    }
                }

            }

        })
    </script>
</body>

</html>

监视属性除了可以监视data里面的值还可以监视计算属性里面的值。我们还可以有下面这种写法:

 const vm=  new Vue({
            el: '#root',
            data: {
                hot: true,  //布尔值
            },

            methods: {
                changeWeather() {
                    this.hot = !this.hot
                }
            },
            // //监视属性
            // watch: {
            //     //需要监视的值
            //     hot: {
            //         //handler什么时候调用?当hot发生改变时调用
            //         handler(newValue,oldValue) {
            //             console.log("hot值被修改了",newValue,oldValue)
            //         }
            //     }

            // }

        })
    
        //第二种写法
        vm.$watch('hot',{
              //handler什么时候调用?当hot发生改变时调用
              handler(newValue,oldValue) {
                        console.log("hot值被修改了",newValue,oldValue)
                    }
        })
2.深度监视

首先说一下 监视多个结构中某个属性的变化

student:{
   name:11,
   age:12
}

需求:检测student中的name的变化,而不是监视student的变化

那么我们上面是监视属性就应该参考下面这种写法:

 watch: {
                //需要监视的值
                hot: {
                    //handler什么时候调用?当hot发生改变时调用
                    handler(newValue,oldValue) {
                        console.log("hot值被修改了",newValue,oldValue)
                    }
                },
                'student.name':{
                    handler(){
                        console.log("name改变了")
                    }
                }

可以看到,我们的写法加上了单引号,这样就可以监视到student中的name的变化了。

假设student中,有很多个类似name的存在,我们如果要监视的这些属性,难道还要单独写很多个这样的监视属性的吗?vue早就给我们想好了,解决这个问题的办法就是深度监视

写法就是在监视属性中加入 deep:true,这样就开启深度监视了,这样就可以监视多级结构中所有属性的变化了。

写法如下:

<!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>vue测试</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>今天天气很{{hot?'热':'冷'}}</h2>
        <button @click="changeWeather">切换天气</button>

        <h3>name的值是:{{student.name}}</h3>
        <button @click="student.name++"> 点我改变name</button>

        <h3>age{{student.age}}</h3>
        <button @click="student.age++"> 点我改变age</button>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                hot: true,  //布尔值
                student:{
                    name:11,
                    age:12,
                }
            },

            methods: {
                changeWeather() {
                    this.hot = !this.hot
                }
            },
            //监视属性
            watch: {
                //需要监视的值
                hot: {
                    //handler什么时候调用?当hot发生改变时调用
                    handler(newValue,oldValue) {
                        console.log("hot值被修改了",newValue,oldValue)
                    }
                },
                student:{
                    deep:true,
                    handler(){
                        console.log("student改变了")
                        console.log(this.student)
                    }
                }
            }
        })
    </script>
</body>

</html>
3.监视属性的简写形式

简写的前提是你不需要 immediate和deep和其他的配置项,也就是你的配置项里面只有handler形式时就可以开启简写形式。

形式:

 watch: {
                hot(newValue,oldValue){
                    console.log("hot值被修改了",newValue,oldValue)
                }
            }

把监视属性写成函数形式即可。