Vue中computed简析

博客基于vue2.x版本,主要对vue中计算属性computed,进行解析

前言:mthods和computed有什么区别?

总所周知,vue中计算属性是带有缓存的,而且很多人会将computedmethod进行比较,诸如method没有缓存啊之类的。这里我通过自己的理解进行一个稍微全面的阐述。

浅显的回答

比较浅显的回答诸如下:

1. 在使用时,computed当做属性使用,而methods则当做方法调用

2. computed可以具有getter和setter,因此可以赋值,而methods不行

3. computed无法接收多个参数,而methods可以

4. computed具有缓存,而methods没有

 上述回答都是比较浅层次的,当然也没有错,不过那只是表面现象,若要深究其理还需要阅读源码才能懂得起,这里我就不带入源码了(其实我也还没阅读源码

 所以这里稍微做一个比较深入但又不那么深入的理解。

深入的回答

vue对methods中的属性怎么处理的呢?

vue对methods就比较简单粗暴了,只需要遍历vue配置中的每一个属性,将其赋值到vue实例上,并使用bind进行函数中上下文对象的绑定

vue对computed中的属性怎么处理的呢?

vue对computed处理就比较复杂,这里引入几个核心属性:

Watcher:监听器,在响应式数据(data)的setter和getter中均有涉及,在setter中用于执行watcher,做到视图依赖该数据的视图更新;在getter中用于产生watcher,记录当前视图和数据的依赖关系

dirty:用来确认当前计算属性是否是脏数据(即已过期),当计算属性所依赖的数据发生改变时(运行setter),对于计算属性的watcher仅做一件事,即将当前计算属性的dirty改为true,标记为已过期

lazy:当前watcher是否立即执行,在当前实例组件中watcher的该属性是true,在计算属性的watcher中该属性是false

value:当前计算属性的值

我们可以先来看一个输出,代码如下:

<template>
  <div>
      <span v-if="showName">{{fullName}}</span>
      <button @click="showName=false, count += 1">click</button>
  </div>
</template>

<script>
export default {
    data() {
        return {
            firstName: "zhang",
            lastName: "san",
            showName: true,
            count: 0
        }
    },
    computed: {
        fullName() {
            console.log("computed function invoked");
            return this.firstName + this.lastName;
        }
    },
    mounted() {
        console.log(this);
    }
}
</script>

 输出如下:

下面截图能够很清楚的看到当使用计算属性时,组件实例中属性_watchers有两个warcher对象,一个是计算属性的,一个是组件实例的,前者lazy属性为true,后者为false,前者dirty为false,因为这个时候计算属性所依赖的数据还未发生改变。

   除此之外,vue在收集watcher的时候,会将计算属性watcher也放入组件实例的,由于组件实例中的那个watcher和_computedWatchers对应的watcher是同一个引用,所以当计算属性的watcher改变时,组件实例的watcher也会改变。

当我们改变计算属性所依赖的数据(调用setter)时,vue会去通知该数据所对应的所有watcher执行一遍更新流程,而计算属性的更新流程就是简简单单地改变dirty为true,使得当前计算属性的值过期。

在watcher执行完之后,组件进入渲染流程(render),根据数据重新去渲染视图时(vue的diff算法),组件实例和计算属性的watcher会去重新收集依赖(getter),这个时候如果发现dirty已经为true,即已过期,那么就会重新去计算计算属性的值并返回,达到计算属性更新的目的

在上述例子中,点击按钮为什么不会再次console呢

至于例子中,点击按钮无法console,原理其实也很简单,因为dom都没有渲染,没有触发计算属性的getter方法,即便dirty变为了true,由于计算属性的watcher中lazy是true,是延迟执行的,所以也就不会输出console(实际上计算属性已经改变了,只是视图中没有用到而已)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值