이 글에서는 주로 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;idefineReactive(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 중국어 웹사이트의 기타 관련 기사를 참조하세요!