Vue 데이터 바인딩에 대한 간략한 분석

高洛峰
풀어 주다: 2017-01-20 10:28:36
원래의
1192명이 탐색했습니다.

서문: 최근 팀에서 공유를 해야 하는데 어떻게 공유해야 할지 몰랐습니다. 마지막으로, 나는 항상 vue 소스 코드를 연구하고 싶다고 생각했고, 오늘 "이 기회를 이용하여" 연구했습니다.

Vue 데이터 바인딩에 대한 기사는 이미 인터넷에 많이 있지만 직접 작성하는 것과 데모를 입력하는 것과 다른 사람의 글을 읽는 것은 전혀 다르기 때문에... 포터들이 옵니다

현재 데이터 바인딩을 구현하는 방법은 크게 세 가지가 있습니다.

1. 더티 값 확인(angular.js) 데이터 변경을 감지하는 폴링

사용자가 텍스트를 입력하는 등의 DOM 이벤트, 버튼 클릭 등. (ng-클릭)

XHR 응답 이벤트($http)

브라우저 위치 변경 이벤트($location)

타이머 이벤트($timeout, $interval)

$digest() 또는 $apply() 실행

2. Object.defineProperty는 객체의 get 및 set을 하이재킹하여 데이터를 모니터링합니다. (vue)

3. 게시자/구독자 모드는 데이터와 뷰의 자동 동기화를 구현합니다.

Object.defineProperty의 장점

"더티 값 감지" - 데이터 변경 마지막으로 데이터가 변경되었는지 확인하기 위해 모든 데이터와 뷰 간의 바인딩 관계에 대해 테스트가 수행됩니다. 변경 사항을 처리하면 다른 데이터에도 추가 변경이 발생할 수 있으므로 이 프로세스는 더 이상 변경되지 않을 때까지 여러 번 순환될 수 있습니다. 데이터가 뷰로 전송되고 페이지가 업데이트되어

Object.defineProperty()가 표시됩니다. 데이터에 대한 작업을 모니터링하고 자동으로 데이터 동기화를 트리거합니다. 또한 동기화가 서로 다른 데이터에 대해 실행되므로 모든 데이터에 대해 테스트를 수행하는 대신 변경 내용을 바인딩된 뷰에 정확하게 전송할 수 있습니다.

Object.defineProperty 사용

var a = {};

Object.defineProperty(a, "b", {

 set: function (newValue) {

 console.log("我被赋值了!" + newValue);

 },

 get: function () {

 console.log("我被取值了!");

 return 2
 }
})

a.b = 3; //我被赋值了!

console.log(a.b); //我被取值了! //打印 2
로그인 후 복사

위의 예에서 볼 수 있듯이 Object.defineProperty는 3개의 매개변수를 전달합니다.

첫 번째 매개변수: 객체

두 번째: 객체의 b 속성

세 번째: 유용한 값을 나열하는 많은 속성이 있으며 설정, 가져오기, 구성 가능

데이터 바인딩 원칙 :

1. 데이터 객체의 모든 속성을 모니터링하는 데이터 리스너 관찰자를 구현합니다. 변경 사항이 있으면 최신 값을 가져와서 dep 배열에 알립니다.

2. 명령어 파서 구현 컴파일, 스캔 및 구문 분석 각 요소 노드의 명령어를 전달하고, 명령어 템플릿

에 따라 데이터를 교체합니다. 3. 각 속성 변경을 구독하고 알림을 받을 수 있는 dep 배열을 구현하고 해당 명령어 바인딩된 콜백 함수를 실행합니다. 업데이트 보기

1. 관찰자 구현

var data = {name: 'beidan'};

observe(data);

data.name = 'test'; // 监听到值变化了 beidan 变成 test

function observe(data) {

 if (!data || typeof data !== 'object') {

 return;

 }

 // 取出所有属性遍历

 Object.keys(data).forEach(function(key) {

  defineReactive(data, key, data[key]);

 });
}
로그인 후 복사
function defineReactive(data, key, val) {


 Object.defineProperty(data, key, {

 enumerable: true, // 可枚举

  configurable: false, // 不能再define
  get: function() {
 
   return val;

  },

  set: function(newVal) {
 
   console.log('监听到值变化了 ', val, ' 变成 ', newVal);

   val = newVal;

  }

 });
}
로그인 후 복사

2. 배열 유지

function Dep() {

 this.subs = [];
}

Dep.prototype = {

 addSub: function (sub) {

 this.subs.push(sub);

 },

 notify: function (val) {

  this.subs.forEach(function (sub) {
 
  sub.update(val)

 });

}
};
function defineReactive(data, key, val) {
 Object.defineProperty(data, key, {
 ……
 set: function(newVal) {
  if (val === newVal) return;
  console.log('监听到值变化了 ', val, ' 变成 ', newVal);
  val = newVal;
  dep.notify(val); // 通知所有订阅者
 }
 });
}
로그인 후 복사


3. 컴파일

bindText: function () {

 var textDOMs = this.el.querySelectorAll('[v-text]'),
bindText,_context = this;


 for (var i = 0; i < textDOMs.length; i++) {
 
 bindText = textDOMs[i].getAttribute(&#39;v-text&#39;);
 textDOMs[i].innerHTML = this.data[bindText];

 var val = textDOMs[i]


 var up = function (text) {
 
  val.innerText = text

 }

 _context.dep.addSub({
 
  value: textDOMs[i],
 
  update: up

 });

 }
},
로그인 후 복사

이 글의 내용이 모두의 공부나 업무에 조금이나마 도움이 되었으면 좋겠습니다.

Vue 데이터 바인딩에 대한 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿