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

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

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

你可能感兴趣的:(vue原理,vue,vue.js,js,proxy)