Vue 监视属性

监视属性——watch

改变天气

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="weather">
    <h2>today is so {{info}}</h2>
    <button @click="changedweather">change the weather</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    const vm=new Vue({
        el: '#weather',
        data:{
            ishot:true
        },
        computed: {
            info(){
                return this.ishot?"hot":"cold"
            }
        }, 

        methods:{
            changedweather(){
                this.ishot=!this.ishot
            }
        }
    })
</script>
</html>

简化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="weather">
    <h2>today is so {{info}}</h2>
    <button @click="ishot=!ishot">change the weather</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    const vm=new Vue({
        el: '#weather',
        data:{
            ishot:true
        },
        computed: {
            info(){
                return this.ishot?"hot":"cold"
            }
        },

        // methods:{
        //     changedweather(){
        //         this.ishot=!this.ishot
        //     }
        // }
    })
</script>
</html>

使用watch监视

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="weather">
        <h2>today is so {{info}}</h2>
        <button @click="changedweather">change the weather</button>
        <span>{{x}}</span>
        <hr>
        <h3>a的值是{{numbers.a}}</h3>
        <button @click="numbers.a++">点我加a</button>
    </div>
    </body>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        const vm=new Vue({
            el: '#weather',
            data:{
                ishot:true,
                x:0,
                numbers:{
                    a:1,
                    b:1,
                }
            },
            computed: {
                info(){
                    return this.ishot?"hot":"cold"
                }
            },

            methods:{
                changedweather(){
                    this.ishot=!this.ishot;
                    this.x++;
                }
            },
            // .vue中的watch默认不监测对象内部值的改变(一层)
            // deep:true可以监测对象内部值改变(多层)
            watch:{
            immediate:true,//初始化时让handler调用
                ishot:{
                    // handler 什么时候调用 当ishot发生改变时
                    handler(newValue,oldValue){
                        console.log(newValue,oldValue);
                    }
                },
                info:{
                    // handler 什么时候调用 当ishot发生改变时
                    handler(newValue,oldValue){
                        console.log(newValue,oldValue);
                    }
                },
                numbers:{
                    deep:true,
                    handler(){
                        console.log("numbers has changed  ");
                    }
                },
                //监测a
                'numbers.a':{
                    handler(newValue,oldValue){
                        console.log(newValue,oldValue);
                    }
                }
        }
    })

    </script>
    </html>

deep进行深度检测

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="weather">
        <h2>today is so {{info}}</h2>
        <button @click="changedweather">change the weather</button>
        <span>{{x}}</span>
        <hr>
        <h3>a的值是{{numbers.a}}</h3>
        <button @click="numbers.a++">点我加a</button>
    </div>
    </body>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        const vm=new Vue({
            el: '#weather',
            data:{
                ishot:true,
                x:0,
                numbers:{
                    a:1,
                    b:1,
                }
            },
            computed: {
                info(){
                    return this.ishot?"hot":"cold"
                }
            },

            methods:{
                changedweather(){
                    this.ishot=!this.ishot;
                    this.x++;
                }
            },
            // .vue中的watch默认不监测对象内部值的改变(一层)
            // deep:true可以监测对象内部值改变(多层)
            watch:{
            immediate:true,//初始化时让handler调用
                ishot:{
                    // handler 什么时候调用 当ishot发生改变时
                    handler(newValue,oldValue){
                        console.log(newValue,oldValue);
                    }
                },
                info:{
                    // handler 什么时候调用 当ishot发生改变时
                    handler(newValue,oldValue){
                        console.log(newValue,oldValue);
                    }
                },
                numbers:{
                    deep:true,
                    handler(){
                        console.log("numbers has changed  ");
                    }
                }
        },
    })

    </script>
    </html>

watch简写

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="weather">
        <h2>today is so {{info}}</h2>
        <button @click="changedweather">change the weather</button>
        <span>{{x}}</span>
        <hr>
        <h3>a的值是{{numbers.a}}</h3>
        <button @click="numbers.a++">点我加a</button>
    </div>
    </body>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        const vm=new Vue({
            el: '#weather',
            data:{
                ishot:true,
                x:0,
                numbers:{
                    a:1,
                    b:1,
                }
            },
            computed: {
                info(){
                    return this.ishot?"hot":"cold"
                }
            },

            methods:{
                changedweather(){
                    this.ishot=!this.ishot;
                    this.x++;
                }
            },
        watch:{
            ishot(newValue,oldValue){
                console.log(newValue,oldValue);
            }
        }
    })

    // vm监视
    vm.$watch('ishot',{
        handler(newValue,oldValue){
                    console.log(newValue,oldValue);
                    }

    })
// vm监视简写
    vm.$watch('ishot',function(newVlaue,oldValue){
        console.log(newValue,oldValue);
    })
    </script>
    </html>

使用watch修改姓名

<!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>
</head>
<body>
    <div id="root">
        姓<input type="text" v-model="firstname">
        名<input type="text" v-model="lastname">
        姓名:<span>{{fullname}}</span>
        </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
 new Vue({
     el:"#root",
     data:{
         firstname:'zhang',
         lastname:'san',
         fullname:'zhang-san'
     },
     watch:{
        firstname(newValue){
            this.fullname=newValue+this.lastname;
        },
        lastname(newValue){
            this.fullname=this.firstname+newValue;
        }
     },
 })
</script>
</html>

watch和computed区别

  1. ocmputed能完成的,watch都能完成
  2. watch能完成的,computed不一定能完成,watch可以执行异步操作

两个重要的小原则

  1. 所有被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
  2. 所有不被Vue所管理的函数(定时器的回调函数,ajax的回调函数),最好写成箭头函数,这样this的指向才是vm或组件实例对象
上一篇:【JS从入门到精通】18-定时调用与延时调用


下一篇:Vue Router的Watch