美文网首页
探索 vue的计算属性

探索 vue的计算属性

作者: Gary嘉骏 | 来源:发表于2018-11-26 13:58 被阅读0次

最近重看 vue 官网,好奇所谓的计算属性是怎么的一回事。官网是这样说的:

计算属性是基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。这就意味着只要 message 没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

另外,依赖必须是响应式依赖,所以若计算属性绑定 Date.now()的话是不会更新的了。

这个在计算复杂比较大的时候是比较有用的,如排序数组然后得到结果。用 methods 的话,每次重新渲染,不管依赖有没有修改,都会重新计算一次,造成较大的浪费。

那为什么一定是响应式依赖呢。为什么计算属性会知道它的依赖是什么呢。对vue的响应式原理了解的人应该能想到大概原理,应该是在getter与setter中里加了逻辑。

大概原理是这样:

  1. 响应式依赖中加逻辑。

  2. 初始化计算属性的值,此时会触发对应依赖的getter,新增的逻辑会记录下来计算方法。

  3. 下次有依赖属性改变时,会在setter中循环记录下来的计算方法,更新计算属性的缓存值。

简单实现逻辑

let data = {
            a: 3
        }

        let comp = {
            b: function () {
                return data.a * 24 + 3
            }
        }

        let computedFn = null;

        function defineReactive(obj, key, val) {
            let deps = [];
            Object.defineProperty(obj, key, {
                get() {
                    if (computedFn) {
                        deps.push(computedFn);
                    }
                    return val;
                },
                set(newVal) {
                    val = newVal;
                    deps.forEach(_ => _());
                }
            })
        }

        function defineCompute(obj, key, computed) {
            let val;
            const fn = function () {
                val = computed();
            }
            computedFn = fn;
            computedFn();
            computedFn = null;
            Object.defineProperty(obj, key, {
                get() {
                    return val;
                }
            })
        }

        defineReactive(data, 'a', data.a);
        defineCompute(comp, 'b', comp.b);

        console.log(b) // 75

        data.a = 1;

        console.log(b) // 27

这个就实现了,其实还是应用了setter 与 getter的钩子

相关文章

网友评论

      本文标题:探索 vue的计算属性

      本文链接:https://www.haomeiwen.com/subject/gqjvqqtx.html