资讯专栏INFORMATION COLUMN

【Vue原理】代理 Data - 源码版

ralap / 2256人阅读

摘要:最后完全不会影响不影响依赖更新赋值,触发代理设置的,就会直接赋值给总部,从而触发设置的,这个,用来依赖更新。

写文章不容易,点个赞呗兄弟
专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧
研究基于 Vue版本 【2.5.17】

如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧

【Vue原理】代理 Data - 源码版

写这篇文章,我就是为了记录我对 Data 的一个疑问的探索,很简短

data 的数据是怎么可以通过实例直接访问的?

第一想法,或许是,遍历逐个复制?

但是其实并不是,这里涉及的一个词,叫 【代理】

怎么代理呢?听我慢慢说,抓住逐个疑问,跟着我慢慢探索



初始化数据

实例使用 initData 初始化数据,如下

function initData(vm) {     

    var data = vm.$options.data;    

    var keys = Object.keys(data);   

    var i = keys.length;

    data = vm._data =

    ( typeof data === "function" ?

        data.call(vm) : data ) || {};   



    while (i--) {   

        var key = keys[i];  

        if (只要不是_和$开头的属性) {
    
            proxy(vm, "_data", key);     
        }   
    } 
    
}

首先,拿到 data 数据,如果data 是函数,就执行拿到返回值,否则直接拿设置的对象data

第二,保存data 数据

源码中你可以看到,把 data 保存到实例上了

vm._data = 
    typeof data === "function" ? 
        data.call(vm) : data

初始化数据,是为了拿到数据,然后放到存到实例上,作为代理总部



2、代理开花

接下来,就放大招了,到了【data 代理】 的重点了,看上面的源码最后

会遍历data对象,如果属性名不是 【_ 或者 $】 开头的话,就会被设置代理

至于为什么避开那两个开头的属性?

Vue官网也说明了

剩下的其他属性,会被设置代理,现在我们来看设置代理的那句话

proxy(vm,"_data",key)

proxy 是什么?不要急,等我放上源码

function proxy(target, sourceKey, key) {    

    Object.defineProperty(target, key, {

        get() {            

            return this[sourceKey][key]

        },

        set(val) {            

            this[sourceKey][key] = val;

        }
    });
}

明白吗?通过 Object.defineProperty 设置 get 和 set 函数,来达到代理,移花接木的过程

可能这么看不太直观,我以一个属性为例写清楚点

于是就会设置成这样

下面是给 _data 属性设置响应式的简化代码

这样的作用,有四个

1、可以直接通过 vm 访问到name

简化写法,你看看 React 这个比,访问 state,需要 http://this.state.xxx 写多一层 很麻烦啊,Vue 做了一层代理就很好,但是呢,成本会大一些

2、保证数据统一

如果是开篇想的那样,逐个赋值,数据改变的时候,就要同时维护两份啊,简直是地狱啊。但是 methods 的处理是直接复制到实例上的

3、不影响依赖收集

当访问 【vm.name】,触发代理 【vm.name 设置的get】,就会访问 【vm._data.name】 ,从而触发总部 【vm._data.name 设置的get】,这个get 用来依赖收集。最后完全不会影响

4、不影响依赖更新

赋值 【vm.name】,触发代理 【vm.name 设置的 set】,就会直接赋值给总部 【vm._data.name】 ,从而触发 【vm._data.name 设置的set 】,这个set,用来依赖更新。最后完全不会影响

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105199.html

相关文章

  • Vue原理】Props - 源码

    写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧 【Vue原理】Props - 源码版 今天记录 Props 源码流程,哎,这东西,就算是研究过了,也真是会随着时间慢慢忘记的。 幸好我做...

    light 评论0 收藏0
  • 用proxy实现一个更优雅的vue

    摘要:以上引用内容来自阮一峰的教程的章节原文地址请戳这里。最后本文最终实现代码已经放在上,想要直接看效果的同学,可以上去直接,运行。 前言 如果你有读过Vue的源码,或者有了解过Vue的响应原理,那么你一定知道Object.defineProperty(),那么你也应该知道,Vue 2.x里,是通过 递归 + 遍历 data对象来实现对数据的监控的,你可能还会知道,我们使用的时候,直接通过数...

    objc94 评论0 收藏0
  • Vue双向绑定的实现原理系列(三):监听器Observer和订阅者Watcher

    摘要:至此监听器和订阅者功能基本完成,后面再加上指令解析器的功能系列文章的目录双向绑定的实现原理系列一双向绑定的实现原理系列二设计模式双向绑定的实现原理系列三监听器和订阅者双向绑定的实现原理系列四补充指令解析器 监听器Observer和订阅者Watcher 实现简单版Vue的过程,主要实现{{}}、v-model和事件指令的功能 主要分为三个部分 github源码 1.数据监听器Obser...

    widuu 评论0 收藏0
  • Vue双向绑定的实现原理系列(三):监听器Observer和订阅者Watcher

    摘要:至此监听器和订阅者功能基本完成,后面再加上指令解析器的功能系列文章的目录双向绑定的实现原理系列一双向绑定的实现原理系列二设计模式双向绑定的实现原理系列三监听器和订阅者双向绑定的实现原理系列四补充指令解析器 监听器Observer和订阅者Watcher 实现简单版Vue的过程,主要实现{{}}、v-model和事件指令的功能 主要分为三个部分 github源码 1.数据监听器Obser...

    legendaryedu 评论0 收藏0
  • 了解MVVM及Vue实现原理,手把手带你撸源码

    摘要:方法实现将所有属性挂载在观察对象,将每一项做一个数据劫持就是将中每一项用定义新属性并返回这个对象。当和发生变化时,自动会触发视图更新,获取得到的也就是最新值。 MVVM及Vue实现原理 Github源码地址:https://github.com/wyj2443573... mvvm 双向数据绑定数据影响视图,视图影响数据angular 脏值检测 vue数据劫持+发布订阅模式vue 不...

    cooxer 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<