Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从vue源码中学习数据代理 #18

Open
lizhongzhen11 opened this issue Dec 19, 2018 · 0 comments
Open

从vue源码中学习数据代理 #18

lizhongzhen11 opened this issue Dec 19, 2018 · 0 comments
Labels
源码 源码

Comments

@lizhongzhen11
Copy link
Owner

lizhongzhen11 commented Dec 19, 2018

起因

最近项目不忙,就自己继续跟着那位滴滴前辈的vue源码分析去看vue源码,不得不说,滴滴前辈真的厉害!今天看到https://ustbhuangyi.github.io/vue-analysis/reactive/reactive-object.html#proxy 这里时,没有第一时间理解,然后自己在控制台尝试去输出才恍然大悟,自己还是菜。。。

利用Object.defineProperty去实现数据代理

这里对应vue源码里的 instance/state.js 中的proxy函数,根据滴滴前辈的分析,这里通过调用proxy函数把每一个值 vm._data.xxx 都代理到 vm.xxx 上;

我一开始看了下代码,根据我的理解,读写vm.xxx时的确是读写vm._data.xxx,但是读写vm._data.xxx的同时也会代理到vm.xxx上我就不理解了,既然光看代码不理解,咱就动手吧。

在chrome控制台测试:

const sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  get: function () {},
  set: function () {}
}

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)
}

let obj = {
  a: {
    a1: 1
  }
}
proxy(obj, 'a', 'a1')
obj // {a: {a1: 1}, a1: 1}
obj.a.a1 = 2
obj // {a: {a1: 2}, a1: 2}

why???amazing!!!

我仔细想了想,a1a都是obj的属性,当打印obj时其实就已经在调用它各个属性的getter方法来获取值了,而proxy函数正好改变了obj.a1settergetter方法!

Proxy

vue源码里也用到了Proxy这个新api,其实我以前看《es6入门》时就没大看懂,今天特地重温了下,豁然开朗。。。不懂得继续看阮一峰前辈的书吧。。。es6入门--Proxy

@lizhongzhen11 lizhongzhen11 added the 源码 源码 label Jul 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
源码 源码
Projects
None yet
Development

No branches or pull requests

1 participant