>  기사  >  웹 프론트엔드  >  Vue 데이터 응답성의 원리에 대한 간략한 논의

Vue 데이터 응답성의 원리에 대한 간략한 논의

不言
不言원래의
2018-05-07 14:38:171441검색

이 글은 주로 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())
  1. 데이터가 변경되면 => 이벤트 트리거
  2. 세 번째 단계를 살펴보겠습니다. 1, 데이터 변경이 후속 이벤트를 어떻게 트리거합니까? 데이터를 변경하려면 먼저 데이터를 설정해야 합니다. 그런 다음 set()에 메서드를 추가하기만 하면 괜찮을 것입니다.
  3. 그리고 또 다른 중요한 질문이 있습니다.


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가지 메소드의 기능만 알면 됩니다.

dependent() --- 이벤트로 이해하면 됩니다. 다른 측면을 고려하지 않고 종속성을 수집하는 함수입니다. addSub()

notify() --- 이 메서드는 더 직관적이며 모든 종속 update() 메서드를 실행합니다. 나중에 보기를 변경하면 됩니다.
  1. 이 글에서는 주로 데이터 응답 과정을 다루며 Watcher 클래스에 대해서는 심도 깊게 다루지 않으므로 Dep.2에서 메소드의 기능만 알면 됩니다.
  2. 그럼 이제 코드를 1.1로 바꿔보겠습니다

//代码 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이 필요한 이유는 무엇입니까?

Dep은 클래스이고 Dep.target은 dep 인스턴스의 속성이 아닌 클래스의 속성입니다.

Dep 클래스는 전역적으로 사용 가능하므로 Dep.target은 전역적으로 액세스할 수 있으며 해당 값을 임의로 변경할 수 있습니다.
  1. get 메소드는 매우 일반적이며 데이터 값을 얻기 위해 사용할 때마다 dep.dependent()를 호출하는 것은 불가능합니다.
  2. dep.dependent()는 실제로 dep.addSub(Dep.target)입니다.
  3. 그럼 가장 좋은 방법은 사용하기 전에 Dep.target을 객체로 설정하고 구독이 완료된 후에 Dep.target = null을 설정하는 것입니다.
  4. 검증

일련의 코드가 유효한지 검증할 시간입니다

//代码 1.4

const obj = {};//这一句是不是感觉很熟悉 就相当于初始化vue的data ---- data:{obj:{}};

//低配的不能再低配的watcher对象(源码中是一个类,我这用一个对象代替了)
const watcher = {
 addDep:function (dep) {
  dep.addSub(this);
 },
 update:function(){
  html();
 }
}
//假装这个是渲染页面的
function html () {
 document.querySelector(&#39;body&#39;).innerHTML = obj.html;
}
defineReactive(obj,&#39;html&#39;,&#39;how are you&#39;);//定义响应式的数据

Dep.target = watcher;
html();//第一次渲染界面
Dep.target = null;

이때 브라우저의 인터페이스는 이렇습니다

그럼 콘솔 아래 디버깅 시작, 입력:

obj.html = &#39;I am fine thank you&#39;

그런 다음 Enter를 누르는 순간 기적이 일어나고 페이지는

End

Vue 데이터 응답이 됩니다. 디자인 패턴은 다음과 같습니다. 구독-게시 패턴과 다소 유사하지만 다릅니다. 각 dep 인스턴스는 구독 센터이며 모든 구독은 각 릴리스와 함께 게시됩니다.

Vue의 반응성 원칙은 실제로 여전히 큰 부분을 차지합니다. 이 기사에서는 Vue가 데이터를 반응시키는 방법을 주로 설명합니다. 그러나 실제로는 하나의 데이터가 여러 곳에서 사용됩니다. , 관찰 방법, 구독 방법, 일정 조정 방법 등 아직 논의되지 않은 내용이 많이 있습니다. 세 가지 주요 클래스인 Dep(종속성 수집), Observer(데이터 관찰) 및 Watcher(구독자, 데이터 변경 시 구독자에게 알림)는 약간만 언급되었습니다.

저는 이전에 Vue의 배열 변환에 대해 논의하는 Vue 응답성 - 배열 돌연변이 방법에 대한 기사를 썼습니다. 물론 나중에 더 많은 기사가 나올 것이고, 전체 데이터 응답 프로세스에는 여전히 많은 내용이 있으며, 세 가지 주요 클래스는 아직 논의되지 않았습니다.

사실 소스코드를 읽는다는 것은 소스코드가 어떻게 동작하는지 알기 위함이기도 하지만, 더 중요하게는 제가 쓴 글이 길지 않아서 한 가지에 집중할 수 있기를 바랍니다. 한 번에 이 지점까지의 원리를 진정으로 이해하십시오. 물론 읽는 시간도 조절해서 중간에 읽고 닫히는 일이 없도록 하고 싶어요.

관련 권장 사항:

Vue 데이터 전송 방법 요약

Vue 데이터 전송 구현 단계 자세한 설명

Vue 데이터 모니터링 방법 시계 사용량

위 내용은 Vue 데이터 응답성의 원리에 대한 간략한 논의의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.