이 글은 vue.js의 반응형 원리에 대한 심층적인 이해를 제공합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다. 당신에게.
저는 그 때 이미 Anglejs가 더티 체크를 통해 데이터 모니터링과 페이지 업데이트 렌더링을 구현한다는 것을 알고 있었습니다. 그 후 vue.js를 접하게 되었는데, 당시 vue.js가 어떻게 데이터 업데이트를 모니터링하고 페이지를 다시 렌더링하는지 매우 궁금했습니다. 오늘은 vue.js 응답성의 원리를 단계별로 분석하고, 간단한 데모를 구현해보겠습니다.
먼저 몇 가지 기본 사항을 이해해 보겠습니다.
###기본 지식
Object.defineProperty
es5에 객체의 속성을 설정할 수 있는 Object.defineProperty API가 추가되었습니다. getter 및 setter를 설정하기 위해 사용자의 값 획득 및 개체 속성 할당을 탈취할 수 있습니다. 예를 들어 다음 코드는 다음과 같습니다.
const obj = { }; let val = 'cjg'; //前端全栈学习交流群:866109386 Object.defineProperty(obj, 'name', { //面向想从事前端开发1到5年及以上工作经验的开发人员 get() { // 帮助突破技术瓶颈,提升思维,欢迎大家进群交流。 console.log('劫持了你的取值操作啦'); return val; }, set(newVal) { console.log('劫持了你的赋值操作啦'); val = newVal; } }); console.log(obj.name); obj.name = 'cwc'; console.log(obj.name);
Object.defineProperty를 통해 obj[name]의 값 획득 및 할당 작업을 하이재킹했으므로 여기서 몇 가지 트릭을 수행할 수 있습니다. obj[ name]에 값이 할당되면 업데이트 페이지 작업이 트리거됩니다.
Publish-Subscribe 패턴
Publish-Subscribe 패턴은 게시자와 구독자라는 두 가지 역할이 있는 일반적인 디자인 패턴입니다. 여러 구독자가 동일한 게시자의 이벤트를 구독할 수 있습니다. 이벤트가 발생하면 게시자는 이벤트를 구독한 모든 구독자에게 알립니다. 이해를 돕기 위해 예를 살펴보겠습니다.
class Dep { //前端全栈学习交流群:866109386 constructor() { //面向想从事前端开发1到5年及以上工作经验的开发人员 this.subs = []; // 帮助突破技术瓶颈,提升思维,欢迎大家进群交流。 } // 增加订阅者 addSub(sub) { if (this.subs.indexOf(sub) { sub.update(); }) } } const dep = new Dep(); const sub = { update() { console.log('sub1 update') } } const sub1 = { update() { console.log('sub2 update'); } } dep.addSub(sub); dep.addSub(sub1); dep.notify(); // 通知订阅者事件发生,触发他们的更新函数
실습
Object.defineProperty와 게시-구독자 모델을 이해하고 나면 생각하는 것이 어렵지 않습니다. vue.js는 위 두 가지를 기반으로 데이터 모니터링을 구현한 것입니다.
vue.js는 먼저 Object.defineProperty를 사용하여 모니터링할 데이터의 getter 및 setter를 하이재킹합니다. 데이터의 속성이 할당/검색되면 vue.js는 그에 따라 처리를 감지하고 응답할 수 있습니다.
구독 게시 모델을 통해 객체의 각 속성에 대한 게시자를 만들 수 있습니다. 다른 구독자가 이 속성에 의존하면 구독자가 게시자의 대기열에 추가됩니다. Object.defineProperty의 데이터 하이재킹을 사용하여 속성의 setter가 호출되면 속성 게시자는 모든 구독자에게 업데이트된 콘텐츠를 알립니다.
다음으로 구현해 보겠습니다(자세한 내용은 댓글 참조):
class Observer { constructor(data) { // 如果不是对象,则返回 if (!data || typeof data !== 'object') { return; } this.data = data; this.walk(); } // 对传入的数据进行数据劫持 walk() { for (let key in this.data) { this.defineReactive(this.data, key, this.data[key]); } } // 创建当前属性的一个发布实例,使用Object.defineProperty来对当前属性进行数据劫持。 defineReactive(obj, key, val) { // 创建当前属性的发布者 const dep = new Dep(); /* * 递归对子属性的值进行数据劫持,比如说对以下数据 * let data = { * name: 'cjg', * obj: { * name: 'zht',//前端全栈学习交流群:866109386 * age: 22, //面向想从事前端开发1到5年及以上工作经验的开发人员 * obj: { // 帮助突破技术瓶颈,提升思维,欢迎大家进群交流。 * name: 'cjg', * age: 22, * } * }, * }; * 我们先对data最外层的name和obj进行数据劫持,之后再对obj对象的子属性obj.name,obj.age, obj.obj进行数据劫持,层层递归下去,直到所有的数据都完成了数据劫持工作。 */ new Observer(val); Object.defineProperty(obj, key, { get() { // 若当前有对该属性的依赖项,则将其加入到发布者的订阅者队列里 if (Dep.target) { dep.addSub(Dep.target); } return val; }, set(newVal) { if (val === newVal) { return; } val = newVal; new Observer(newVal); dep.notify(); } }) } } // 发布者,将依赖该属性的watcher都加入subs数组,当该属性改变的时候,则调用所有依赖该属性的watcher的更新函数,触发更新。 class Dep { constructor() { this.subs = []; } addSub(sub) { if (this.subs.indexOf(sub) { sub.update(); }) } } Dep.target = null; // 观察者 class Watcher { /** *Creates an instance of Watcher. * @param {*} vm * @param {*} keys * @param {*} updateCb * @memberof Watcher */ constructor(vm, keys, updateCb) { this.vm = vm; this.keys = keys; this.updateCb = updateCb; this.value = null; this.get(); } // 根据vm和keys获取到最新的观察值 get() { Dep.target = this; const keys = this.keys.split('.'); let value = this.vm; keys.forEach(_key => { value = value[_key]; }); this.value = value; Dep.target = null; return this.value; } update() { const oldValue = this.value; // 前端全栈学习交流群:866109386 const newValue = this.get(); // 面向想从事前端开发1到5年及以上工作经验的开发人员 if (oldValue !== newValue) { // 帮助突破技术瓶颈,提升思维,欢迎大家进群交流。 this.updateCb(oldValue, newValue); } } } let data = { name: 'cjg', obj: { name: 'zht', }, }; new Observer(data); // 监听data对象的name属性,当data.name发现变化的时候,触发cb函数 new Watcher(data, 'name', (oldValue, newValue) => { console.log(oldValue, newValue); }) data.name = 'zht'; // 监听data对象的obj.name属性,当data.obj.name发现变化的时候,触发cb函数 new Watcher(data, 'obj.name', (oldValue, newValue) => { console.log(oldValue, newValue); }) data.obj.name = 'cwc'; data.obj.name = 'dmh';
Conclusion
이런 식으로 간단한 응답 데이터 모니터링이 완료되었습니다. 물론 이것은 vue.js의 응답성 원칙을 설명하기 위한 간단한 데모일 뿐입니다. 실제 vue.js 소스 코드는 다른 많은 로직이 추가되기 때문에 더욱 복잡해집니다.
위 내용은 vue.js 응답성 원칙에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

JavaScript는 웹 사이트, 모바일 응용 프로그램, 데스크탑 응용 프로그램 및 서버 측 프로그래밍에서 널리 사용됩니다. 1) 웹 사이트 개발에서 JavaScript는 HTML 및 CSS와 함께 DOM을 운영하여 동적 효과를 달성하고 jQuery 및 React와 같은 프레임 워크를 지원합니다. 2) 반응 및 이온 성을 통해 JavaScript는 크로스 플랫폼 모바일 애플리케이션을 개발하는 데 사용됩니다. 3) 전자 프레임 워크를 사용하면 JavaScript가 데스크탑 애플리케이션을 구축 할 수 있습니다. 4) node.js는 JavaScript가 서버 측에서 실행되도록하고 동시 요청이 높은 높은 요청을 지원합니다.

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.

C와 C는 주로 통역사와 JIT 컴파일러를 구현하는 데 사용되는 JavaScript 엔진에서 중요한 역할을합니다. 1) C는 JavaScript 소스 코드를 구문 분석하고 추상 구문 트리를 생성하는 데 사용됩니다. 2) C는 바이트 코드 생성 및 실행을 담당합니다. 3) C는 JIT 컴파일러를 구현하고 런타임에 핫스팟 코드를 최적화하고 컴파일하며 JavaScript의 실행 효율을 크게 향상시킵니다.

실제 세계에서 JavaScript의 응용 프로그램에는 프론트 엔드 및 백엔드 개발이 포함됩니다. 1) DOM 운영 및 이벤트 처리와 관련된 TODO 목록 응용 프로그램을 구축하여 프론트 엔드 애플리케이션을 표시합니다. 2) Node.js를 통해 RESTFULAPI를 구축하고 Express를 통해 백엔드 응용 프로그램을 시연하십시오.

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

드림위버 CS6
시각적 웹 개발 도구

WebStorm Mac 버전
유용한 JavaScript 개발 도구

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.
