搜索
写经验 领红包
 > 知识

vue计算属性原理(vue的计算属性和方法有什么区别)

导语:从源码中学Vue(三)深入理解计算属性computed原理

vue计算属性原理(vue的计算属性和方法有什么区别)

欢迎来到我的《从源码中学Vue》专题系列文章,更多精彩内容持续更新中,欢迎关注 :)

上一章节我们通过源码分析了Vue中的methods对象下的方法是如何挂载到vm下,以及各方法内部的this为何是指向了vm对象。

其实在Vue中,还有一个特别有用的API,那就是computed计算属性,那么我们接下来就通过源码看看它内部做了什么吧!

本章目标

computed运行效果computed源码中做了什么?

欲分析源码,我们首先要搞清楚在Vue中,computed是如何工作的。

请看示例:

大概说下computed计算属性的用法,它本身是一个对象,对应的key值都将会被Object.defineProperty给兼听到,也可以将对应的key直接像data中的数据一样绑定到我们的模板字符串中去渲染。

接下来我们去看下里面的源码吧。

首先还是找到对应的文件:node_modules\vue\src\core\iinstance\state.js

和之前说到的methods源码一样,它有一个initComputed方法,核心源码就在这个方法中,走,进去看看。

在第175行中,源码开始使用for in去遍历对象,接下来我们看下这段源码

首先,我们通过const userDef = computed[key]获取到computed对象的中的value值,这个值的类型可以是function,也可以是对象,但是如果是对象的话,那么这个对象下一定要实现一个ge对象,否则会报Getter is missing for computed property

也就是说,我们还可以这样写

我们将total写成一个对象,然后实现一个get方法

继续往下看

const isSSR = isServerRendering()

这段表示是否是SSR(服务器渲染),一般来说,我们的项目都是非服务器渲染的。所以这个isSSR返回一个false.

紧接着,如果是非SSR下,我们则给每一个computed属性生成一个Watch实例,用于检测computed的变化。

这里我们着重来看下这个参数:computedWatcherOptions,源码在前面是这样定义的。

lazy:true,这一点在后面会非常有用

wather等我们后面涉及到兼听的时候再去看源码。

再拄后是这样的:

判断我们在computed中的key值是否在我们的data或者props中定义过,如果定义了,则抛出异常,没有定义那就是开始调用defineComputed(vm, key, userDef)函数。

到这里,核心函数来啦,我们去看下defineComputed(vm, key, userDef)函数的实现吧。

先来看我圈出来的两行代码,源码通过Object.defineProperty(target, key, sharedPropertyDefinition)来检测vm对象的comouted中的key的变化。

再来看

const shouldCache = !isServerRendering()

非服务器渲染环境下,需要缓存,这里就开始引出了,computed的特点来了,缓存

从源码看,如果是需要缓存的话,还调用了createComputedGetter方法,接下来我们去找这个方法的定义。

源码根据compued对象下的key值找到对应的watcher对象,然后判断对象是否dirty

如果dirty了,那就是调用watcher.evaluate()方法

接下来有必要去翻翻watch类中具体实现了。

找到watcher.js

我先看到了这个dirty属性。

可以看出来,这个dirty是和我们传入的lazy相关,前面我们说到在实现化watcher的时候,默认传入了{lazy:true}

所以第一次我们会调用 wather.evaluate()方法,我们再来看下evaluate方法的实现。

当dirty为true的时候,我们将get到的值赋给了this.也就是我们的wather对象的value属性上,并且将我们的dirty设置为false,

也就是说在调用 createComputedGetter 函数的时候,当我们的watcher对象的dirty属性为false的时候,就直接返回watcher对象的value属性值。

dirty英文意思为脏的。也步是当数据有变化的时候,我们的computed属性对就去做相应的get调用,否则直接返回wather实例上的value属性

PS:了解angular1.x的童鞋可能知道,它里面的双向数据绑定原理就是脏值检查(dirtycheck)

总结:

computed中的key不能与data,props,methods中的key相同。在computed下的value值可以是一个函数,也可以是一个对象,为对象的时候,必须得实现一个get对象(一般为方法)computed中的属性可以直接绑定到模板字符串中。一般来说涉及到两个data中的数据的相互计算的时候,我们使用计算属性会比较合理。源码中直接给computed对象中的key进行了数据绑定。

这里是畅哥聊技术 《从源码中学Vue》系列文章,更多精彩内容持续更新中,敬请期待。

未完待续。。。

本文内容由小媛整理编辑!