疑问
在初学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
的响应式原力???