疑问
在初学 vue 的时候, 我发现了一个神奇的事情, 在 props 和 data 里的属性, methods 里面的方法, 居然能够通过 this.xx 直接使用.
new Vue({data:{words:'hello'},
created(){
console.log(this.words); // 居然可以打印出 hello 来
}
});
这特么是一种武功? 在下第一个不服, 打算一探究竟.
偷师学艺
熟话说, 知己知彼才能百战不殆, 待在下偷看一下 Vue 的武功秘籍, 想好对策, 再去上门踢馆. 然后当上总经理, 出任 CEO, 迎娶白富美, 走上人生的巅峰.
Object.defineProperty
是 Vue 中重要的组成部分, 不了解的童鞋先查看一下文档, Object.defineProperty() .
我把这一招称作隔山打牛大法, 果然是奇妙无穷, 在下偷学了他的武功心法, 为了让更多的人学会这一招, 在下演练一下低配版的隔山打牛.
function proxy(target, source) {
for (let key in source) {
Object.defineProperty(target, key, {
enumerable: true,
configurable: true,
get: function() {
return source[key];
},
set: function(val) {
source[key] = val;
}
});
}
}
const father = {};
const child = {
money: 100
}
proxy(father, child);
father.money // 100
招式其实很简单, 在调用 proxy 方法之后, 每次去获取 father 的 money 的时候, return 的是 child 的 money, 设置的时候也是这样的.
拓展
Vue 中的
Props,data,methods
都是使用的这一招定义到 vm 上的. 那么在组件中, data 必须使用函数和这货有没有关系呢?
其实并没有什么关系, 但是我们可以通过 proxy 反推.
在构建组件实例的时候会传入 option, 里面有一系列的属性与方法.
Vue.component('my-component', {
template: '<span>{{ message }}</span>',
data: {
message: 'hello'
}
});
每次实例化组件的时候, 都会使用这个引用地址相同的 data 来传入 proxy 中. 那么虽然有多个实例, 但实际上隔山打的都是同一个牛.
如果 data 是一个函数, 那么就会执行函数, 返回一个新的 data 对象, 这样隔山打牛就是不同的牛了.
data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {}
登门踢馆
在下也学会了隔山打牛, Vue 你就等死吧.(当上总经理, 出任 CEO, 迎娶白富美, 走上人生的巅峰.)
Vue:???
Vue: 隔山打牛只是
Object.defineProperty
用法的一种, 虽然你知道了可以直接用 this.xx 来访问属性与方法, 但是你知道我是如何做到响应式的吗? 你个辣鸡.
Vue: 来吧, 在下不动, 让你三招.
我:(怎么办, 不是对手啊, 慌的一批)
我: 我媳妇昨天出门做头发回来了, 这次在下就放你一马.(跑跑跑)
哎, 居然不是对手, 还是继续回去修习吧. 我还是去修习那啥, 他说的那个啥, Vue 的响应式原力???
Vue 响应式 ---- 数据响应式原理 .
来源: https://juejin.im/post/5a7037b15188257324727a77