为什么直接访问this可以获取到data和methods?
当我们初学Vue时,会发现在new Vue实例时,直接在实例上可以直接访问到data和methods,有没有深入思考过框架是如何实现的呢?
const vm = new Vue({
data: {
name: '我是DG',
},
methods: {
sayName(){
console.log('sayName', this.name);
}
},
});
console.log('name', vm.name); // 输出我是DG
vm.sayName() // 直接执行vue的methods对象中的方法
原理解答
接下来,我们会用一个最简单的demo去理解其中的原理
- 在
initMethod
中,遍历methods
对象,使用bind
将每一个method
拓展在pm实例
中 - 将
data代理到_data
中,将私有变量_data暴露给pm实例
以下代码是具体两点的实现:
var target = {
enumerable: true,
configurable: true,
get: {},
set: {}
};
function proxy (target, sourceKey, key) {
target.get = function proxyGetter () {
return this[sourceKey][key]
};
target.set = function proxySetter (val) {
this[sourceKey][key] = val;
};
Object.defineProperty(target, key, target);
}
// 原理:遍历methods对象,使用bind将每一个method拓展在pm实例中
// 效果:pm实例中便具有了methods中的每个method
function initMethod(pm, methods) {
Object.keys(methods).map(key => {
pm[key] = methods[key].bind(pm);
});
}
// 原理
// 将data代理到_data中,将私有变量_data暴露给pm实例
// 在_data中,我们同样会监听data的改变,做数据响应操作
function initData(pm,datas) {
var _data = {};
pm._data = datas;
const key = Object.keys(datas)
proxy(pm, "_data", key);
}
function Person(args) {
var pm = this;
pm.$options = args;
const { methods = {}, data = {} } = args;
initMethod(pm, methods); // 初始化method
initData(pm, data); // 初始化data
return pm;
}
const person = new Person({
data: {
name: 'dk1'
},
methods: {
sayName(){
console.log('sayName1', this._data.name);
}
}
});
person.sayName()
关键词:构造函数
this 指向
call、bind、apply
Object.defineProperty
等等基础知识。
结语:学习框架思想会让我们将基础在实际的应用中巩固的更加牢固,构建自己的学习框架,应对问题时会更加有解决思路