이 글은 주로 Vue 데이터 응답성의 원리를 소개합니다. 이제 여러분과 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다.
Vue의 데이터 응답은 주로 객체에 달려 있습니다. .defineProperty(), 전체 프로세스는 어떤가요? 우리 자신의 아이디어로 Vue의 길을 걷는다는 것은 실제로 Vue의 원칙을 최종점으로 삼는 것을 의미합니다. 이 문서의 코드는 모두 로우 프로파일 버전이며 많은 부분이 엄격하지 않습니다. 예를 들어 if(typeof obj === 'object')는 obj가 객체일 수도 있지만 obj가 객체인지 여부를 결정하는 것입니다. array 또는 다른 유형의 데이터를 사용하지만 단순화를 위해 이 기사에서는 판단 개체를 나타내기 위해 직접 작성하고 배열에는 Array.isArray()를 사용합니다.
데이터 변환
먼저 객체를 변환하는 함수를 작성해 보겠습니다. 왜 이 함수를 먼저 작성해야 할까요? 데이터 변환은 가장 기본적이고 중요한 단계이므로 이후의 모든 단계는 이 단계에 따라 달라집니다.
// 代码 1.1 function defineReactive (obj,key,val) { Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get: function () { return val; }, set: function (newVal) { //判断新值与旧值是否相等 //判断的后半段是为了验证新值与旧值都为NaN的情况 NaN不等于自身 if(newVal === val || (newVal !== newVal && value !== value)){ return ; } val = newVal; } }); }
예를 들어 const obj = {}이고, 이때 함수 내에서 val=2이고 그 다음 값이 나올 때마다 DefineReactive(obj,'a',2) 메서드를 호출합니다. of obj.a를 얻습니다. 모두 val 값을 가져오고, obj.a를 설정할 때 val 값도 설정합니다. (defineReactive가 호출될 때마다 val 값을 저장하기 위해 클로저가 생성됩니다.)
프로세스 토론
검증 결과 실제로 이 함수를 사용할 수 있는 것으로 확인되었습니다. 그런 다음 응답 프로세스에 대해 논의해 보겠습니다.
데이터 입력
데이터 변환(defineReactive())그리고 또 다른 중요한 질문이 있습니다.
Dependency Collection
데이터 변경 후 어떤 이벤트가 트리거될지 어떻게 알 수 있나요? Vue에서:데이터 사용 => 뷰를 렌더링하는 데 데이터가 사용되므로 데이터를 얻을 때 종속성을 수집하는 것이 가장 좋습니다. Vue는 수집 의존을 위해 데이터 속성을 변환할 때 Dep 인스턴스를 생성합니다.
// 代码 1.2 class Dep { constructor(){ //订阅的信息 this.subs = []; } addSub(sub){ this.subs.push(sub); } removeSub (sub) { remove(this.subs, sub); } //此方法的作用等同于 this.subs.push(Watcher); depend(){ if (Dep.target) { Dep.target.addDep(this); } } //这个方法就是发布通知了 告诉你 有改变啦 notify(){ const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update(); } } } Dep.target = null;
Code 1.2는 Dep의 코드의 일부입니다. 당분간은 2가지 메소드의 기능만 알면 됩니다.
//代码 1.3 function defineReactive (obj,key,val) { const dep = new Dep(); Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get: function () { if(Dep.target){ //收集依赖 等同于 dep.addSub(Dep.target) dep.depend() } return val; }, set: function (newVal) { if(newVal === val || (newVal !== newVal && val !== val)){ return ; } val = newVal; //发布改变 dep.notify(); } }); }
이 코드에 의문점이 있는데, Dep.target이 무엇인가요? 종속성을 수집하기 위해 Dep.target이 필요한 이유는 무엇입니까?
//代码 1.4
const obj = {};//这一句是不是感觉很熟悉 就相当于初始化vue的data ---- data:{obj:{}};
//低配的不能再低配的watcher对象(源码中是一个类,我这用一个对象代替了)
const watcher = {
addDep:function (dep) {
dep.addSub(this);
},
update:function(){
html();
}
}
//假装这个是渲染页面的
function html () {
document.querySelector('body').innerHTML = obj.html;
}
defineReactive(obj,'html','how are you');//定义响应式的数据
Dep.target = watcher;
html();//第一次渲染界面
Dep.target = null;
이때 브라우저의 인터페이스는 이렇습니다
그럼 콘솔 아래 디버깅 시작, 입력:
obj.html = 'I am fine thank you'
그런 다음 Enter를 누르는 순간 기적이 일어나고 페이지는
End
Vue 데이터 응답이 됩니다. 디자인 패턴은 다음과 같습니다. 구독-게시 패턴과 다소 유사하지만 다릅니다. 각 dep 인스턴스는 구독 센터이며 모든 구독은 각 릴리스와 함께 게시됩니다.Vue의 반응성 원칙은 실제로 여전히 큰 부분을 차지합니다. 이 기사에서는 Vue가 데이터를 반응시키는 방법을 주로 설명합니다. 그러나 실제로는 하나의 데이터가 여러 곳에서 사용됩니다. , 관찰 방법, 구독 방법, 일정 조정 방법 등 아직 논의되지 않은 내용이 많이 있습니다. 세 가지 주요 클래스인 Dep(종속성 수집), Observer(데이터 관찰) 및 Watcher(구독자, 데이터 변경 시 구독자에게 알림)는 약간만 언급되었습니다.
저는 이전에 Vue의 배열 변환에 대해 논의하는 Vue 응답성 - 배열 돌연변이 방법에 대한 기사를 썼습니다. 물론 나중에 더 많은 기사가 나올 것이고, 전체 데이터 응답 프로세스에는 여전히 많은 내용이 있으며, 세 가지 주요 클래스는 아직 논의되지 않았습니다.
사실 소스코드를 읽는다는 것은 소스코드가 어떻게 동작하는지 알기 위함이기도 하지만, 더 중요하게는 제가 쓴 글이 길지 않아서 한 가지에 집중할 수 있기를 바랍니다. 한 번에 이 지점까지의 원리를 진정으로 이해하십시오. 물론 읽는 시간도 조절해서 중간에 읽고 닫히는 일이 없도록 하고 싶어요.
관련 권장 사항:
위 내용은 Vue 데이터 응답성의 원리에 대한 간략한 논의의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!