Vue框架 - computed 与 watch 之间的那点事儿

computed 与 watch 之间的那点事儿

computed

  • 计算属性的值
    在依赖数据发生改变时 / 或者没有依赖数据时
    会自动缓存到应用中,下次获取时,不重新计算
  • 计算得到的数据
    • computed 是一个对象,里面存放是属性,类似 data 而不是methods
    • 里面的属性可以像 data 里面存放的数据一样去使用
    • 这些属性的值是通过运算得到的
    • 它的结构类似(defineProperty), getter , setter
    • 计算属性的值同时还会根据它所依赖的数据变化 而自动变化
    <div id="app">
        <button @click="showData=!showData">click</button>
        <p v-if="showData">实时数据:{{getNow()}}</p>
        <p v-if="showData">computed 的数据:{{now}}</p>
    </div>

    <script>
        let app = new Vue({
            el:"#app",
            data:{
                showData:true
            },
            methods:{
                getNow(){
                    return Date.now()
                }
            },
            computed:{
            	// 完整的写法如下:
                // now:{
                //     get(){
                //         return Date.now();
                //     }
                // },
                /*
                *  如果某个计算属性只需要处理 get方法,那么可以简写
                *   只是简写,并不是直接放置方法
                */  
                now(){
                    return Date.now();
                }
            }
        });
    </script>
  • 多次点击按钮
    查看 computed 的监听性质
    实时数据一直改变,computed 的数据并没有发生改变
    在这里插入图片描述

watch

计算属性 / 计算数据 / 派生数据

  • watch 异步的派生数据
    可以用来直接处理异步
    可以达到主动监听的效果,只要监听的属性或者数据发生变化,立即触发事件
监听不同类型数据
  • 简单数据类型监听
	watch:{
 		// users 需要监听的数据(属性)
 		// (){} 数据发生改变时 调用的回调函数
 		users(){
 			console.log(111)
 			if (this.users.every(user => user.checked == true)) {
 		 		this.checkAll = true;
 			}else{
 		 		this.checkAll = false;
 			}
 		}
 	}
  • 数组类型数据监听
	watch:{
 		showUsers:{
			// watch  默认监听数据一层
			// 深度监听 handler 方法和 deep 属性结合
			handler(arr){
				// console.log(arr);
				let all = arr.every(user => user.checked == true);
				console.log(all);
				if (all == true ) {
						this.checkAll = true;
				}else{
						this.checkAll = false;
				}
			}
		},	
 	}
  • 多层对象数据监听
	watch: {
		'a.b.c': function() {
			//...
		}
	}
模拟实例

搜索框失去焦点立即触发事件
修改显示元素的 display 属性

    <style>
        .active{
            color: coral;
            font-weight: bold;
        }
    </style>

    <div id="app">
    	<!-- 
			通过 v-model 实现监听事件
		 -->
        输入性别: <input type="text" v-model.lazy="keyWord">
        <ul>
            <li v-for="user in showUsers">
                <input type="checkbox" v-model="user.checked">
                {{user.name}}-{{user.sex}}
            </li>
        </ul>
    </div>

    <script>
        let users = [
            {id:1,name:"秦",age:"23",sex:"男",checked:false},
            {id:2,name:"兟",age:"22",sex:"男",checked:false},
            {id:3,name:"李",age:"24",sex:"女",checked:false},
            {id:4,name:"武",age:"23",sex:"女",checked:false},
        ]
        let app = new Vue({
            el:"#app",
            data:{
                keyWord:"",
                users,
                showUsers:[]
            },
            watch:{
            	// v-model 监听的 keyWord 事件
                keyWord(){
                    // includes(指定的内容); 是否包含指定的值
                    this.showUsers = this.users.filter(user => user.sex.includes(this.keyWord))
                }
            }
        });
    </script>

在这里插入图片描述

computed 和 watch 的区别

对于数据的处理:
  • computed : 依赖数据变化才去计算
  • watch: 主动处理数据变化
是否处理异步(能否主动监听)
  • computed: 没法处理异步的数据
  • watch:可以直接处理异步
使用场景
  • computed: 适合的场景 多个数据影响一个数据
    数据不独立的场景
  • watch:适合的场景 一个数据影响多个数据
    适合处理数据相互独立的场景

watch实现

会有一定的弊端,watch 实现全选的写法上会有自身的问题

    <div id="app">
        <button :class="{active:sex===''}" @click = "sex=''">全部</button>
        <button :class="{active:sex==='男'}" @click = "sex='男'">男</button>
        <button :class="{active:sex==='女'}" @click = "sex='女'">女</button>
        <hr>
        <ul>
            <li v-for="user in showUsers">
                <input type="checkbox" v-model="user.checked">
                {{user.name}}-{{user.sex}}-{{user.age}}
            </li>
        </ul>
        <input type="checkbox" v-model="checkAll">全选
    </div>

    <script>
        let users = [
            {id:1,name:"秦",age:"23",sex:"男",checked:false},
            {id:2,name:"兟",age:"22",sex:"男",checked:false},
            {id:3,name:"李",age:"24",sex:"女",checked:false},
            {id:4,name:"武",age:"23",sex:"女",checked:false},
            {id:5,name:"谭",age:"22",sex:"女",checked:false}
        ]

        let app = new Vue({
            el:"#app",
            data:{
                sex:"",
                users,
                checkAll:false,
                showUsers:users
            },
            /* 监听某一个对象 */ 
            watch:{
                sex(){
                    this.showUsers = this.users;
                    if (this.sex != "") {
                        this.showUsers = this.users.filter(user => user.sex == this.sex);
                    }
                },
                checkAll(){
                    if (!this.showUsers.some(e => e.checked)) {
                        this.users.forEach(el => {
                            el.checked = this.checkAll;
                        });
                    }
                },
                // 数组的类型监听
                showUsers:{
                    // watch  默认监听数据一层
                    // 深度监听 handler 方法和 deep 属性结合
                    handler(arr){
                        // console.log(arr);
                        let all = arr.every(user => user.checked == true);
                        console.log(all);
                        if (all == true ) {
                            this.checkAll = true;
                        }else{
                            this.checkAll = false;
                        }
                    },
                    immediate:true, // 主动执行一次
                    deep:true // 默认 false 只监听一层 
                }
            }
        });
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值