Vue源码学习之数据初始化
首发地址: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'
}
})
一开始我想是将data和methods中的数据全都挂载到了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源码学习之数据初始化的更多相关文章
- vue 源码学习二 实例初始化和挂载过程
vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- Vue 源码学习(1)
概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- VUE 源码学习01 源码入口
VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...
随机推荐
- 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)
传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...
- 不同类型input尺寸设置区别
最近发现为不用类型的input设置相同的尺寸,却得到了不一样的尺寸结果.发现不同类型的input的height和width竟然含义不同.在此小整理一下. (1)button类型 规律 button类型 ...
- python中报中文编码异常,Non-ASCII ,but no encoding declared
异常信息: SyntaxError: Non-ASCII character '\xe5' in file a.py on line 9, but no encoding declared; see ...
- CSS样式基础:
CSS:外部文件导入 <link rel="stylesheet" type="text/css" href="./style.css&quo ...
- Luogu 2668 [NOIP2015]斗地主
打牌技术不精,没有把$A$放在顺子里面搜,WA了好长时间. 盗用大佬的一张图: 当时自己搜的时候没有把四张牌拆成三带一等情况. 然后还有一点就是四张三张都出完之后直接数一数剩下的一张两张牌还要多少次出 ...
- Swoole 整合成一个小框架
目录 概述 效果 代码 小结 概述 这是关于 Swoole 学习的第六篇文章:Swoole 整合成一个小框架. 第五篇:Swoole 多协议 多端口 的应用 第四篇:Swoole HTTP 的应用 第 ...
- Python中的try和except语句
Python中是通过缩进来解析代码块的,要特别注意tab和空格符,两者不可以混用,通常情况下用四个空格来代替tab键 下面通过一个简单的例子来说明 提示用户输入工作的时间和每小时的时薪,如果超过40个 ...
- Codeforces Round#522 Div2E(思维,背包,组合数学)
#include<bits/stdc++.h>using namespace std;int a[107];int b[10007][107];int c[107][107];int ma ...
- PAT1098【插入排序+堆排序】
简单插入排序: 简单插入排序的核心思想: 把一条这么个难看的序列默认分为两个排好序的和未排好序的两个部分: 所以一开始排好序的只有一个a[0](好看的只有一个),难看的有N(数组长度)-1个a[1,n ...
- Hadoop eclipse plugin
我的eclipse是在win7上,hadoop在win7里的虚拟机里的ubuntu上,为了方便起见,想在eclipse上安装hadoop的插件,主要参考 https://my.oschina.net/ ...