vue2.0 응답성을 구현하는 방법(자세한 튜토리얼)

亚连
풀어 주다: 2018-06-05 17:48:44
원래의
1742명이 탐색했습니다.

이 글에서는 주로 vue2.0 반응성을 구현하는 기본 아이디어를 소개하고 참고하겠습니다.

최근에 응답성 구현에 대한 vue2.0 소스 코드를 읽었습니다. 다음 블로그 게시물에서는 간단한 코드를 통해 응답성에 대한 vue2.0의 구현 아이디어를 복원합니다.

이것은 단지 구현 아이디어를 복원한 것에 불과합니다. 배열의 데이터 작업 모니터링, 객체 중첩 등 다양한 세부 사항의 구현은 이 예제에서 다루지 않습니다. 구현을 수행하려면 소스 코드 관찰자 폴더와 인스턴스 폴더의 상태 파일을 읽어서 이에 대해 자세히 알아볼 수 있습니다.

먼저 vue 객체의 구조를 정의합니다

class Vue {
  constructor(options) {
    this.$options = options;
    this._data = options.data;
    this.$el = document.querySelector(options.el);
  }
}
로그인 후 복사

1단계: 데이터 아래의 속성을 관찰 가능으로 변경합니다.

Object.defineProperty를 사용하여 데이터 객체의 속성 가져오기 및 설정을 모니터링합니다. 데이터입니다. 작업을 읽고 할당할 때 노드의 명령어가 호출되므로 가장 일반적인 = 등호를 사용하는 할당이 트리거될 수 있습니다.

//数据劫持,监控数据变化
function observer(value, cb){
 Object.keys(value).forEach((key) => defineReactive(value, key, value[key] , cb))
}

function defineReactive(obj, key, val, cb) {
 Object.defineProperty(obj, key, {
  enumerable: true,
  configurable: true,
  get: ()=>{
   return val
  },
  set: newVal => {
   if(newVal === val)
    return
   val = newVal
  }
 })
}
로그인 후 복사

두 번째 단계: 메시지 구독자 구현

은 매우 간단합니다. 이 배열에 구독자를 넣습니다. 알림이 트리거되면 구독자는 매번 자체 업데이트 메소드

class Dep {
 constructor() {
  this.subs = []
 }
 add(watcher) {
  this.subs.push(watcher)
 }
 notify() {
  this.subs.forEach((watcher) => watcher.cb())
 }
}
로그인 후 복사

를 호출합니다. 함수가 호출되면 업데이트를 구현하기 위해 알림을 트리거합니다

그런 다음 문제가 발생합니다. 구독자는 누구입니까? 네, 와쳐입니다. . dep.notify()가 구독자, 즉 Watcher를 순회하고 그의 update() 메소드

function defineReactive(obj, key, val, cb) {
 const dep = new Dep()
 Object.defineProperty(obj, key, {
  enumerable: true,
  configurable: true,
  get: ()=>{
   return val
  },
  set: newVal => {
   if(newVal === val)
    return
   val = newVal
   dep.notify()
  }
 })
}
로그인 후 복사

를 호출하면 3단계: Watcher 구현

실제로 데이터를 수행할 때 Watcher 구현은 비교적 간단합니다. 변경 사항, 수행할 작업

class Watcher {
 constructor(vm, cb) {
  this.cb = cb
  this.vm = vm
 }
 update(){
  this.run()
 }
 run(){
  this.cb.call(this.vm)
 } 
}
로그인 후 복사

4단계: 종속성을 가져오기 위한 터치

위의 세 단계에서 우리는 데이터 변경이 업데이트를 트리거할 수 있다는 것을 깨달았습니다. 이제 문제는 감시자를 우리와 연결할 수 없다는 것입니다. 데이터.

우리는 데이터의 속성이 DefineReactive로 설정된 후 데이터의 값을 수정하면 설정이 트리거된다는 것을 알고 있습니다. 그런 다음 데이터의 상위 값을 가져오면 get이 트리거됩니다. 따라서 이를 활용하고 먼저 다음 렌더링 기능을 실행하여 뷰를 업데이트하고 이를 데이터 구독자로 기록하는 데 필요한 데이터 지원이 무엇인지 알 수 있습니다.

function defineReactive(obj, key, val, cb) {
 const dep = new Dep()
 Object.defineProperty(obj, key, {
  enumerable: true,
  configurable: true,
  get: ()=>{
   if(Dep.target){
    dep.add(Dep.target)
   }
   return val
  },
  set: newVal => {
   if(newVal === val)
    return
   val = newVal
   dep.notify()
  }
 })
}
로그인 후 복사

마지막으로 프록시를 사용하여 데이터 액세스를 vue 객체에 바인딩하는 방법을 살펴보겠습니다

 _proxy(key) {
  const self = this
  Object.defineProperty(self, key, {
   configurable: true,
   enumerable: true,
   get: function proxyGetter () {
    return self._data[key]
   },
   set: function proxySetter (val) {
    self._data[key] = val
   }
  })
}

Object.keys(options.data).forEach(key => this._proxy(key))
로그인 후 복사

다음은 전체 인스턴스의 전체 코드입니다

class Vue {
 constructor(options) {
  this.$options = options;
  this._data = options.data;
  this.$el =document.querySelector(options.el);
  Object.keys(options.data).forEach(key => this._proxy(key))
  observer(options.data)
  watch(this, this._render.bind(this), this._update.bind(this))
 }
 _proxy(key) {
  const self = this
  Object.defineProperty(self, key, {
   configurable: true,
   enumerable: true,
   get: function proxyGetter () {
    return self._data[key]
   },
   set: function proxySetter (val) {
    self._data[key] = val
   }
  })
 }
 _update() {
  console.log("我需要更新");
  this._render.call(this)
 }
 _render() {
  this._bindText();
 }

 _bindText() {
  let textDOMs=this.$el.querySelectorAll('[v-text]'),
  bindText;
  for(let i=0;i defineReactive(value, key, value[key] , cb))
}

function defineReactive(obj, key, val, cb) {
 const dep = new Dep()
 Object.defineProperty(obj, key, {
  enumerable: true,
  configurable: true,
  get: ()=>{
   if(Dep.target){
    dep.add(Dep.target)
   }
   return val
  },
  set: newVal => {
   if(newVal === val)
    return
   val = newVal
   dep.notify()
  }
 })
}
function watch(vm, exp, cb){
 Dep.target = new Watcher(vm,cb);
 return exp()
}

 class Watcher {
 constructor(vm, cb) {
  this.cb = cb
  this.vm = vm
 }
 update(){
  this.run()
 }
 run(){
  this.cb.call(this.vm)
 } 
}

class Dep {
 constructor() {
  this.subs = []
 }
 add(watcher) {
  this.subs.push(watcher)
 }
 notify() {
  this.subs.forEach((watcher) => watcher.cb())
 }
}
Dep.target = null; 
var demo = new Vue({
 el: '#demo',
 data: {
 text: "hello world"
 }
 })
 
setTimeout(function(){
 demo.text = "hello new world"
 
}, 1000)

 
  

로그인 후 복사

위는 전체 vue 데이터에 대한 전체 아이디어입니다. 구동 부분. 구현에 대해 더 자세히 알고 싶다면 vue 코드 중 이 부분을 자세히 살펴보는 것이 좋습니다.

위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다.

관련 기사:

vue+element-ui+ajax를 사용하여 테이블 인스턴스 구현

live-server를 사용하여 로컬 서버를 구축하고 자동으로 새로 고치는 방법, 구체적인 방법은 무엇입니까?

낮은 버전의 브라우저에서 es6 가져오기를 지원하지 않는 문제 해결

위 내용은 vue2.0 응답성을 구현하는 방법(자세한 튜토리얼)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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