一般写Vue时,不管是在methods,还是filters,亦或者mounted中,直接使用this访问data的数据或者访问methods方法
this指向的是谁,为什么这样用,带着疑问接着往下看!
new Vue({
el: "#root",
data: {
a: 1,
b: 2,
},
methods: {
fn() {
console.log(this.a, this.b)
}
},
mounted() {
this.fn()
}
})
理解之前,先理解一个方法
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
太官方,不好理解?下面好理解
const obj = {
userName:"小学"
}
let studyName = obj.userName;
//该方法相当于一个拦截器
Object.defineProperty(obj,"userName",{
//第一个参数是对象,需要拦截的对象
//第二个参数是拦截的的属性
//第三个参数是描述行为
// 当你获取该属性时会执行get方法。该方法返回的值即是最终读取的值
get(){
console.log("读取");
return studyName;
},
// 设置,当你对数据进行写入时,会执行set方法
// v:是准备写入的内容
set(v){
studyName = v;
console.log("写入",v);
}
})
// 设置userName属性值
obj.userName = "中学";
// 获取userName属性值
console.log(obj.userName); //该结果就是get中返回的值
//输出结果为
/*写入 中学
读取
中学*/
接下来 重头戏
//option就是 实例中的参数对象
function Mao(options) {
// 将options的data属性赋值给属性$data
if (options.data) {
//把参数中的data放入构造函数中
this.$data = options.data;
//把 this.$data中属性生成一个数组
const arr=Object.keys(this.$data)
let len=arr.length;
while(len--){
const key=arr[len];
//当设置数据时,会触发set方法,获取是触发get方法
Object.defineProperty(this, key, {
get() {
return this.$data[key];
},
set(v) {
this.$data[key] = v;
}
})
}
}
if (options.methods) {
for (let key in options.methods) {
//当设置方法时,会触发set方法,获取是触发get方法
Object.defineProperty(this, key, {
get() {
//这里没有this,是因为Vue中没有methods对象,通过拦截,间接调用方法
return options.methods[key]
},
set(v) {
options.methods[key] = v;
}
})
}
}
if (options.mounted) {
//改变this指向
options.mounted.call(this);
//当Vue中有mounted 自动执行
options.mounted()
//执行时 会执行this.fn() 会被options.methods中拦截 间接调用methods中的方法
}
}
new Mao({
el: "#root",
data: {
a: 1,
b: 2,
},
methods: {
fn() {
console.log(this.a, this.b)
}
},
mounted() {
this.fn() // 1 2
//当执行this.fn()时 会在options.methods中拦截 且输出options.methods[key]=>options.methods[fn]() 执行fn中的程序
}
})