首发地址:CJWbiu's Blog

  在这里思考一个问题,使用Vue的时候需要在创建Vue实例时传入一个option,这里包含了我们定义的props、methods、data等。而在methods的方法中获取data中的key值都是直接通过this.key获取option对象中的methods中的定义的方法如何通过this访问到data中的数据呢?

let vue = new Vue({
el: '#app',
methods: {
say() {
console.log(this.msg)
}
},
data: {
msg: 'jjjjj'
}
})

  一开始我想是将datamethods中的数据全都挂载到了vm上,然而Vue实例上有methods中定义的方法,却没有data中的属性,data中的数据全部存储在vm._data中,通过this.key访问其实是this._data.key,Vue在这里做了一层代理,通过defineProperty设置了vm的getter和setter,而methods中的方法在initMethods方法中将其中的this绑定到了vm上,这样methods中方法访问的this也就指向了_data

  下面是参照源码相关逻辑的简化代码:

function MyVue(option) {
this._init(option);
} MyVue.prototype._init = function(option) {
const vm = this;
vm.$options = option; //源码在此做了对子组件option的合并处理
if(vm.$options.methods) initMethods(vm, vm.$options.methods); //源码中还有对props的处理,data、props、methods都会做查重处理,不能有相同的属性名
if(vm.$options.data) initData(vm);
} function initMethods(vm, methods) {
const props = vm.$options.props
for (const key in methods) {
vm[key] = methods[key].bind(vm); //将methods上的方法挂载到vm上并将方法中所有的this指向vm,通过下面的proxy就可以访问到_data上的属性
}
} function initData(vm) { //将data上数据复制到_data并遍历所有属性添加代理
vm._data = vm.$options.data;
const keys = Object.keys(vm._data);
let i = keys.length;
while(i--) {
const key = keys[i];
proxy(vm, `_data`, key);
}
}
function proxy(target, sourceKey, key) {
let sharedPropertyDefinition = {};
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
}
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val
}
Object.defineProperty(target, key, sharedPropertyDefinition) //一层代理,每次访问this[key]时代理到this._data[key]
} let app = new MyVue({
methods: {
say: function() {
console.log(this.msg + this.age);
}
},
data: {
msg: 'jjj',
age: 33
}
})
app.say(); //jjj33

Vue源码学习之数据初始化的更多相关文章

  1. vue 源码学习二 实例初始化和挂载过程

    vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...

  2. 【Vue源码学习】依赖收集

    前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...

  3. Vue源码学习1——Vue构造函数

    Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...

  4. Vue源码学习三 ———— Vue构造函数包装

    Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...

  5. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  6. 最新 Vue 源码学习笔记

    最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...

  7. Vue 源码学习(1)

    概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...

  8. 【Vue源码学习】响应式原理探秘

    最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...

  9. VUE 源码学习01 源码入口

    VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...

随机推荐

  1. 使用Visual Studio进行单元测试-Shim类中无法找到参数包含CancellationTokenSource的方法

    Shim类中无法找到参数包含CancellationTokenSource的方法,这句话有点绕口,看例子. 一.代码 public class CancellationDemo { public in ...

  2. Maven 排除依赖jar包

    当我们引入第三方jar包的时候,难免会引入传递性依赖,有些时候这是好事,然而有些时候我们不需要其中的一些传递性依赖 比如我们不想引入传递性依赖commons-logging,我们可以使用exclusi ...

  3. codeblocks如何支持_tmain?可移植代码的编码推荐

    codeblocks默认源代码文件编码根据OS而定,编译时编码UTF-8. 在你不更改任何codeblocks配置时:                    在WINDOWS中:源代码——WINDOW ...

  4. Linux keepalived与lvs的深入分析

    一)概述 在本篇文章里,我们会涉及两部份内容,一个是LVS,另一个则是keepalived. 即我们用LVS和keepalived实现了负载均衡及高可用的服务器.   LVS有实现三种IP负载均衡技术 ...

  5. tomcat部署虚拟主机-搭建两个应用以及httpd和Nginx的反向代理

    实验环境:CentOS7 前提:已经安装好tomcat,未安装请查看http://www.cnblogs.com/wzhuo/p/7111135.html: 目的:基于主机名访问两个应用: [root ...

  6. 针对nginx的内核优化

    关于内核参数的优化: net.ipv4.tcp_max_tw_buckets = 6000timewait的数量,默认是180000.net.ipv4.ip_local_port_range = 10 ...

  7. java 正则表达式 验证邮箱

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class demo1 { /**java正则表达式 * ...

  8. nodejs PK php全方位比较PHP的Node.js的优缺点

    全方位比较PHP的Node.js的优缺点 http://www.techug.com/php-vs-node-js

  9. Unity编辑器的扩展:IMGUI

    IMGUI 介绍 所有关于 Editor 的相关 UI,包括 Inspector.Hierarchy.Window.Game 视图上动态创建的那些半透明 UI.还有 Scene 视图上可添加的辅助显示 ...

  10. nodejs assert 模块

    assert模块是Node的内置模块,主要用于断定.如果表达式不符合预期,就抛出一个错误.该模块提供11个方法,但只有少数几个是常用的. 1.assert() assert(value[, messa ...