vue中的computed、watch(immediate、deep)区别

vue中的computed

注意:vue实例中data中的属性名不能和methods、computed中的属性名重名。

computed是vue实例中的计算属性,存在缓存机制,只有它所依赖的属性值发生变化才会重新计算,否则默认走缓存。这样节省性能。

当一个属性依赖多个属性或多个属性的变化会影响另一个属性时,这个属性可以放在computed中进行处理。

当一个属性依赖多个属性时一般可以采用computed方式,当该属性依赖的其他属性发生变化时,会立即调用该属性的get方法重新计算当前的属性值并重新渲染页面。

一般放在computed中属性可以为其添加get和set方法。如果只需要对该属性设置get方法可以简写。

computed与methods的区别:computed是计算属性,默认走缓存,当依赖的属性发生变化,就会执行对应的getter方法,如果多次访问同一个属性不需要多次执行该函数,它会走缓存。但是methods中定义的函数一般是在调用时执行,不存在缓存机制。

<div id="app">
    <!-- 当input点击时,执行的事件函数获取的还是checkbox框没有被点击前的值,所以此处要用change事件,不能使用click事件 -->
    <input type="checkbox" v-model="selectAll">全选{{selectAll}}<br/>
    <!--上面代码中虽然获取了两次selectAll的值,但是实际代码执行时只执行了一次selectAll的get方法,因为computed计算属性默认走缓存-->
    <ul>
        <li v-for="a in arr">
            <input type="checkbox" v-model="a.isSelected">{{a.name}}
        </li>
    </ul>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",//元素选择器
        data: {//data中的属性不能和methods、computed中重名
            arr:[{isSelected:true,name:"手机"},{isSelected:false,name:"电脑"}]
        },
        computed:{
            selectAll:{
                get(){
                    // 函数中this指向当前实例,当这个get函数变为箭头函数时this指向window,此时可以给这个箭头函数传递一个形参,该形参就是vue实例
                    return this.arr.every(item=>item.isSelected); 
                },
                set(val){
                    // 会默认将最新设置的值传给第一个形参,当改变selectAll的值时就会调用set方法。此处在设置selectAll值的目的是更新所有li中的isSelected属性值
                    this.arr.forEach(item=>item.isSelected = val);
                }
            }
            // 如果当前的属性只有获取数据,没有设置数据那么可以如下方式书写
            // selectAll(){
            //     return this.arr.every(item=>item.isSelected);
            // }
        }
    });
</script>

vue中的watch

watch只能监听data中现有的属性,只要监听的属性发生变化就会触发监听函数执行。

<div id="app">
<!--点击按钮改变属性a的值-->
{{a}}<button @click="fn">改变</button>
</div>
let vm = new Vue({
    el:"#app",
    data:{
        a:100
    },
    methods:{
        fn(){
            this.a = 200;
        }
    },
    watch:{
        // 下面这种监听方式有一个特点第一次绑定时不执行的该监听函数的,只有监听的属性值发生变化才执行此函数
        a(newVal,oldVal){//只要监听到属性a的值发生变化就会触发该监听函数执行
            //newVal表示改变后的值
            //oldVal表示改变前的值
            console.log(newVal);//200
            console.log(oldVal);//100
        }
    }
});

vue实例computed和watch比较

<div id="app">
    姓:<input type="text" v-model="firstName"><br/>
    名:<input type="text" v-model="lastName"><br/>
    全名:{{fullName}}
</div>
<!-- computed实现由姓和名获取全名的方法 -->
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            firstName:"",
            lastName:""
        },
        computed:{
            fullName(){//fullName的get方法,在它依赖的属性发生变化时才会调用该函数执行
                return this.firstName + this.lastName;
            }
        }
    });
</script>
<!-- watch实现由姓和名获取全名的方法 -->
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            firstName:"",
            lastName:"",
            fullName:""
        },
        watch:{//watch中只能监听data中存在的属性,当属性值发生变化时调用对应的方法
            firstName(newVal){
                this.fullName = newVal + this.lastName;
            },
            lastName(newVal){
                this.fullName = this.firstName + newVal;
            }
        }
    });
</script>

computed和watch的区别

  • 1、computed默认走缓存,减少性能消耗;watch不走缓存
  • 2、computed不支持异步;watch支持异步
  • 3、当一个属性依赖多个属性时使用computed(多对一);当一个属性变化会引起多个操作时使用watch(一对多)

watch中的immediate、deep属性

上面的举例中watch监听函数在第一次绑定时不执行,只有在监听到的属性值发生变化才会执行对应的监听函数。现在可以利用watch中的immediate属性让watch中监听函数在第一次绑定时就执行。

<div id="app">
    姓:<input type="text" v-model="firstName"><br/>
    名:<input type="text" v-model="lastName"><br/>
    全名:{{fullName}}
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            firstName:"",
            lastName:"",
            fullName:""
        },
        watch:{
            firstName:{
                handler(newVal,oldVal){
                    this.fullName = newVal + this.lastName;
                },
                immediate:true//将immediate属性设置为true后在第一次绑定firstName属性时就会触发监听函数执行
            },
            lastName:{
                handler(newVal,oldVal){
                    console.log(newVal,oldVal);
                    this.fullName = this.firstName + newVal;
                },
                immediate:true
            }
        }
    });
</script>

从上面的举例中可以看出,在给 firstName 绑定了一个handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。而immediate:true代表如果在 wacth 里声明了 firstName 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。

可以通过设置watch中的deep属性值为true,实现通过设置一个对象的监听函数,就可以监听到该对象中的属性值发生的变化。

<div id="app">
    姓:<input type="text" v-model="person.firstName"><br/>
    名:<input type="text" v-model="person.lastName"><br/>
    全名:{{person.fullName}}
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            person:{
                firstName:"",
                lastName:"",
                fullName:""
            }
        },
        watch:{
            person:{
                handler(newVal,oldVal){
                    this.person.fullName = this.person.firstName + this.person.lastName;
                },
                immediate:true,
                deep:true//通过设置deep属性值为true可以保证在person中的属性值发生变化就会执行该监听函数
            }
            // 上面使用deep属性对person的监听可以写成下面的方式,针对data中的对象的单个属性进行监听
            // 'person.firstName':{
            //     handler(newVal,oldVal){
            //         this.person.fullName = newVal + this.person.lastName;
            //     }
            // },
            // 'person.lastName':{
            //     handler(newVal,oldVal){
            //         this.person.fullName = this.person.firstName + newVal;
            //     }
            // }
        }
    });
</script>
发布了19 篇原创文章 · 获赞 3 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/u010510187/article/details/100165237
今日推荐