Vueレスポンシブ原則
1.ガイダンス
1.MVVMパターン
Vueがモデル、ビュー-モデル、ビューを含むMVVMパターンであることは誰もが知っています。
模板:
<div>年龄:{
{age}}</div>
数据变化:
this.age ++;
データが変化すると、それに伴ってビューも変化します。ここで、ビューモデルが機能します。
2.侵入型および非侵入型
侵入型とは、関数を呼び出さずにデータを直接変更することでビューを変更できることを意味します。
邪魔にならないのは、データを変更する関数を呼び出してビューを変更することです。
那为什么Vue可以实现非侵入式的效果的——如何实现数据响应式?
第二に、Object.defineProperty()の理解-応答性の中核
Object.defineProperty()メソッドは、オブジェクトに直接新しいプロパティを定義するか、オブジェクトの既存のプロパティを変更して、オブジェクトを返します。
可以检测对象属性变化,实现数据劫持和数据代理
1、値、書き込み可能、列挙可能
var obj = {
};
Object.defineProperty(obj, 'a', {
//给a属性定义值
value: 6,
//是否可写
writable: false,
//是否可以被枚举
enumerable: true
})
Object.defineProperty(obj, 'b', {
//给a属性定义值
value: 10,
//是否可以被枚举
enumerable: false
})
console.log('obj.a', obj.a);//6
obj.a = 10
console.log('obj.a', obj.a);//6:因为设置了不可写
for (const key in obj) {
console.log('可枚举', key);//只会输出a,因为b设置了不可被枚举
}
2、get、set
var obj = {
};
Object.defineProperty(obj, 'c', {
//getter:数据劫持
get() {
console.log("正在访问c属性")
},
//setter
set() {
console.log('正在改变c属性')
}
})
obj.c++;//自增有访问也有改变
obj.c = 10;//赋值只有改变
console.log(obj.c);//undefined
3、defineReactive関数(カスタム関数)
obj.cが未定義であるという問題を解決します
因为getter函数(get)需要有一个返回值,这个返回值就是属性的值(get和value不能共存)
var obj = {
};
Object.defineProperty(obj, 'c', {
//getter:数据劫持
get() {
console.log("正在访问c属性");
return 7
},
//setter
set() {
console.log('正在改变c属性')
}
})
obj.c++;//自增有访问也有改变
obj.c = 10;//赋值只有改变
console.log(obj.c);//7
当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
var obj = {
};
Object.defineProperty(obj, 'c', {
//getter:数据劫持
get() {
console.log("正在访问c属性");
return 7
},
//setter
set(newValue) {
console.log('正在改变c属性', newValue)
}
})
obj.c++;//自增有访问也有改变
obj.c = 10;//赋值只有改变
console.log(obj.c);//7 因为get返回的依旧是7
最终解决方案:
var obj = {
};
var temp;
Object.defineProperty(obj, 'c', {
//getter:数据劫持
get() {
console.log("正在访问c属性");
return temp;
},
//setter
set(newValue) {
console.log('正在改变c属性', newValue)
temp = newValue
}
})
obj.c++;//自增有访问也有改变
obj.c = 10;//赋值只有改变
console.log(obj.c);//10
成功修改!!!
自定义defineReactive函数
//自定义defineReactive函数
function defineReactive(data, key, val) {
Object.defineProperty(data, key, {
//可枚举
enumerable: true,
//可以被delete
configurable: true,
//getter:数据劫持
get() {
console.log("正在访问" + key + "属性");
return val;
},
//setter
set(newValue) {
console.log("正在改变" + key + "属性", newValue)
if (val !== newValue) {
val = newValue
}
}
})
}
var obj = {
};
defineReactive(obj, 'c', 10)
console.log(obj.c);//10
3.オブジェクトのすべてのプロパティの再帰的検出(Observer、observe、defineReactiveはループと再帰的な関係です)
マルチレイヤーオブジェクトのハイジャックは、上記で定義したdefineReactive関数を使用して実行することはできません。
//自定义defineReactive函数(data->要访问的对象,key->对象中的属性,val->要修改的属性值【闭包】)
function defineReactive(data, key, val) {
console.log("defineReactive", key);
//可以传两个参数
if (arguments.length === 2) {
val = data[key]
}
observe(val);
Object.defineProperty(data, key, {
//可枚举
enumerable: true,
//可以被delete
configurable: true,
//getter:数据劫持
get() {
console.log("正在访问" + key + "属性");
return val;
},
//setter
set(newValue) {
console.log("正在改变" + key + "属性", newValue)
if (val !== newValue) {
val = newValue
observe(newValue);
}
}
})
}
//设置属性能否被枚举
function def(data, key, value, enumerable) {
Object.defineProperty(obj, key, {
value,
enumerable,
writable: true,
configurable: true
})
}
//能将object转化为每个层级的属性都是响应式的——可以被侦测的object
class Observer {
constructor(value) {
//给实例添加__ob__属性,不可以被枚举,value为实例
def(value, '__ob__', this, false);
console.log("构造器", value)
this.walk(value)
}
//遍历
walk(value) {
for (const key in value) {
defineReactive(value, key)
}
}
}
//创建observe函数,首先判断
function observe(val) {
if (typeof val !== 'object') return;
var ob;
if (typeof val.__ob__ !== 'undefined') {
ob = val.__ob__;
} else {
ob = new Observer(val);
}
return ob
}
var obj = {
a: {
m: {
n: 5
}
},
b: 10
}
observe(obj);
console.log(obj.a.m.n);
上記はVueリアクティブの原則(defineProperty、defineReactive、Observer)です。オブジェクトオブジェクトのコンテンツです。「フロントエンドインタビューの質問」列に注目してください。
私の通常のプロジェクトに共通する問題と筆記試験の知識を共有し、CSDNであなたと面接し、一緒に進歩します。さあ。