vue中的监视属性

案例  页面有一行文字,今天天气状况炎热/凉爽,这个炎热和凉爽是动态变化的,通过按钮点击切换
      实现方法同样有许多种,简单的就是用三元表达式写在插值表达式({{ 三元表达式 }})里面,但依旧不太好(逻辑长)
      还可以定义点击事件,在点击事件执行的方法里面进行判断data属性里面的值,如果是炎热就修改属性值为凉爽~如果凉爽则修改为炎热
      也可以用computed计算属性,插值表达式里面写计算属性,计算属性里面判断后返回文字,点击事件需要修改data属性值,(如例一)
      基于计算属性,可以用简便方法,如例子二直接在点击事件里面写表达式



案例一:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<!---->

<!-- 例一 -->
<div id = "app">
    今天天气情况:{{fun}}
    <button @click="funClick">切换</button>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data :{
            weather: true
        },
        computed: {//计算属性    传入配置对象
            fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法
                return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热
            }
        },
        methods: {
            funClick(){//点击事件
                this.weather = !this.weather;//取反以后再赋值给data里面的属性
            }
        }
    })
</script>
</body>
</html>

 

例二:点击事件可以不用写一个函数,可以直接在里面写表达式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<!---->

<!-- 例一 -->
<div id = "app">
    今天天气情况:{{fun}}
    <button @click="weather = !weather">切换</button>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data :{
            weather: true
        },
        computed: {//计算属性    传入配置对象
            fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法
                return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热
            }
        },
        methods: {
            /*funClick(){//点击事件
                this.weather = !this.weather;//取反以后再赋值给data里面的属性
            }*/
        }
    })
</script>
</body>
</html>

 

但是当我们还需要做一些其他操作时,比如需要提示天气降温添加衣服时,就需要监听天气状态,当天气状态发生改变时做出提示,就需要用到监视属性了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<!--

-->

<!-- 例一 -->
<div id = "app">
    今天天气情况:{{fun}}  {{tip}}
    <button @click="weather = !weather">切换</button>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data :{
            weather: true,
            tip: ""
        },
        computed: {//计算属性    传入配置对象
            fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法
                return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热
            }
        },
        methods: {
            //因为点击事件已经直接在上面写了表达式,所以不需要再写方法
        },
        watch: {//监听,同样传入一个配置对象
            weather: {//名对应data中的属性,表示监听weather的数据变化情况
                immediate: false,//true表示初始化时调用一次handler
                handler(newValue,oldValue){//写handler函数,该函数在监听的属性发生变化时会调用执行,有两个参数,第一个参数是新值,第二个是旧值
                    /*
                    * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑
                    * */
                    console.log("" , newValue , oldValue )
                    if (this.weather == true){
                        this.tip = "请注意降温";
                    }
                }
            }
        }
    })
</script>
</body>
</html>

另外,它不仅可以监听data里面的属性,还可以监听计算属性里面的东西,当计算属性发生了改变,它也可以达到同等的效果

 

同时,它还有其他的写法,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<!--

-->

<!-- 例一 -->
<div id = "app">
    今天天气情况:{{fun}}  {{tip}}
    <button @click="weather = !weather">切换</button>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data :{
            weather: true,
            tip: ""
        },
        computed: {//计算属性    传入配置对象
            fun(){//当不需要set时,可以用这种简便方法写,它默认调用的get方法
                return this.weather ? "凉爽" :"炎热";//如果weather为true则返回凉爽,false则返回炎热
            }
        },
        methods: {
            //因为点击事件已经直接在上面写了表达式,所以不需要再写方法
        },
        /*watch: {//监听,同样传入一个配置对象
            weather: {//名对应data中的属性,表示监听weather的数据变化情况
                immediate: false,//true表示初始化时调用一次handler
                handler(newValue,oldValue){//写handler函数,该函数在监听的属性发生变化时会调用执行,有两个参数,第一个参数是新值,第二个是旧值
                    /!*
                    * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑
                    * *!/
                    console.log("" , newValue , oldValue )
                    if (this.weather == true){
                        this.tip = "请注意降温";
                    }
                }
            }
        }*/
    })
    //在保证vm已经被实例化的前提下,监视还可以这样写
    vm.$watch("weather",{//第一个参数传入需要监视的属性,第二个参数传入配置对象,配置对象内容跟上面一模一样
        immediate: false,//true表示初始化时调用一次handler
        handler(newValue,oldValue){//写handler函数,该函数在监听的属性发生变化时会调用执行,有两个参数,第一个参数是新值,第二个是旧值
            /*
            * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑
            * */
            console.log("" , newValue , oldValue )
            if (this.weather == true){
                this.tip = "请注意降温";
            }
        }
    })
</script>
</body>
</html>

 

 

vue的多层级的监视(监视test下的a属性):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<!--

-->

<!-- 例一 -->
<div id = "app">
    <span>a的值{{test.a}}</span>
    <button @click="test.a++">a++</button>

    <span>b的值{{test.b}}</span>
    <button @click="test.b++">b++</button>

</div>
<script>
    var vm = new Vue({
        el: "#app",
        data :{
            test:{
                a: 1,
                b: 2
            }
        },
        computed: {//计算属性    传入配置对象
        },
        methods: {
        },
    })
    //在保证vm已经被实例化的前提下,监视还可以这样写
    //vue的深度监视(监视多级下的某个属性,必须写全),如果想要监视test下的a的话,则需要用引号引起来并逐级,而如果想要监听某个属性里面的全部属性的话,则需要
    vm.$watch('test.a',{//第一个参数传入需要监视的属性,第二个参数传入配置对象,配置对象内容跟上面一模一样
        deep: true,//而如果想要监听某个属性里面的所有属性的变化的话,则需要添加这个配置,目前是监听了a里面所有的属性变化
        immediate: false,//true表示初始化时调用一次handler
        'handler'(newValue,oldValue){//
            /*
            * 可以在这里面添加其他逻辑,比如在监听到属性发生改变时,提示天气炎热需要加衣服等等其他逻辑
            * */
            console.log("" , newValue , oldValue )
        }
    })
</script>
</body>
</html>

 

最后补充一下,vue的计算属性和监视属性在实现功能上,可能会有重合的地方,比如一个需求可以用计算属性实现也可以用监视属性实现(我前面的计算属性那个案例就可以用监视属性实现),这种情况哪种简单就用哪种。但是~~~还有一种情况,可能必须要用监视属性实现,比如同样是那个计算属性的案例,它需要在name变化后一秒再执行,因为计算属性展示的是计算属性里面的返回值,当你用了延时执行方法后,return就变成了延时执行方法的返回值了,而不是计算属性的返回值,页面得不到计算属性的返回值就会出问题,这种情况只能用监视属性,因为监视属性没有返回值,它是直接通过代码修改了data里面的属性,导致页面数据展示发生改变。

但是~~~还有一个注意事项,如果在监视属性里面写延时函数的话,必须要用箭头函数写,因为用普通函数写的话,this表达的就不是vm实例对象了,将无法通过代码给vm的data属性重新赋值。

 

 

总结

1.所有被vue管理的函数,最好写成普通函数,这样this的只想才是vm 或者组件实例对象

2.所有不被vue管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数( ()=>{} )这样this的指向才是vm或者组件实例对象

posted @ 2021-12-09 18:04  名难  阅读(254)  评论(0编辑  收藏  举报