vue源码学习(第一张)this访问data数据
前言
本文章,为了让大家理解为什么我们实例化Vue对象中我们可以用this来访问data中的数据。这里我们大部分都是用的源码,简化的部分很少,但是还是有所修剪。
我们使用的函数
Vue | Vue对象 |
---|---|
initData | 初始化我们的data数据 |
getData | 如果data是函数的话我们用此方法来取得函数的返回值 |
proxy | 实现this指向的函数 |
// Vue对象
function Vue(options) {
this.initData(options)
}
// 初始化我们的data数据
Vue.prototype.initData = (vm) => {
let data = vm.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
let keys = Object.keys(data)
for (const item in keys) {
proxy(vm,'_data', keys)
}
}
// 如果data是函数的话我们用此方法来取得函数的返回值
function getData(data, vm) {
return data.call(vm,vm)
}
// 实现this指向的函数
let sharedPropertyDefinition = {}
function proxy(target, sourceKey, key) {
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
}
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val
}
Object.defineProperty(target, key, sharedPropertyDefinition)
}
每个函数的初步讲解
Vue函数
这个函数没什么好讲的,他只是调用了许多的方法来初始化,渲染等我们的传入的数据
initData
// Vue对象
function Vue(options) {
this.initData(options)
}
// 初始化我们的data数据
Vue.prototype.initData = (vm) => {
let data = vm.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
let keys = Object.keys(data)
for (const item in keys) {
proxy(vm,'_data', keys)
}
}
const vue = new Vue({
data(){
return {
sdaasd: 'asdasd'
}
}
})
在我们实例化Vue函数的时候,我们同时调用了绑定在Vue函数原型上的initData函数。
首先定义了一个data变量来保存我们实例化Vue传入的options
中的data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
这个data数据不仅仅保存在了我们的函数中他还挂在在了vm对象上。这个语句做出了一个判断,如果是data是对象的话我们直接拿到他的数据就好,如果不是对象是个函数,那我们就执行getData这个函数
为什么这么做呢?
是为了防止Object.defineProperty
这个API
的死循环,用过的都知道如果set中返回的还是自己get中的数据那么他就又会执行get,这样无限的死循环,非常难受。
function getData(data, vm) {
return data.call(vm,vm)
}
他其实也就是一个call方法执行了一下函数拿到了返回值。
然后我们创建了keys
变量来保存data中所有的键。并执行proxy()
函数
let sharedPropertyDefinition = {}
function proxy(target, sourceKey, key) {
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
}
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val
}
Object.defineProperty(target, key, sharedPropertyDefinition)
}
proxy(vm,'_data', keys)
我们通过传参看看proxy()
函数做了什么。
他的get
和set
方法实际上是改变了this访问时的指向,如果你知道Object.defineProperty
这个api
到这里其实你已经明白他的原理了,他就是给每个变量做了代理。