vue源码学习(第一张) this访问data数据 拆散之后并不难

vue源码学习(第一张)this访问data数据

前言

本文章,为了让大家理解为什么我们实例化Vue对象中我们可以用this来访问data中的数据。这里我们大部分都是用的源码,简化的部分很少,但是还是有所修剪。

我们使用的函数

VueVue对象
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()函数做了什么。

他的getset方法实际上是改变了this访问时的指向,如果你知道Object.defineProperty这个api到这里其实你已经明白他的原理了,他就是给每个变量做了代理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值