Detailed explanation of vue.js responsiveness principle (with code)
This article brings you a detailed explanation of the responsiveness principle of vue.js (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
I have been exposed to angularjs a long time ago. At that time, I already understood that angularjs implements data monitoring and page update rendering through dirty checking. After that, I came into contact with vue.js. At that time, I was very curious about how vue.js monitors data updates and re-renders the page. Today, we will analyze the principle of vue.js responsiveness step by step, and implement a simple demo.
First, let us understand some basic knowledge.
Basic knowledge
Object.defineProperty
es5 has added the Object.defineProperty API, which allows us to set getters and setters for the properties of objects, so that we Can hijack the user's value acquisition and assignment of object properties. For example, the following code:
const obj = { }; let val = 'cjg'; Object.defineProperty(obj, 'name', { get() { console.log('劫持了你的取值操作啦'); return val; }, set(newVal) { console.log('劫持了你的赋值操作啦'); val = newVal; } }); console.log(obj.name); obj.name = 'cwc'; console.log(obj.name);
We hijacked the value acquisition and assignment operations of obj[name] through Object.defineProperty, so we can do some tricks here, for example, we can use obj[name] Triggers the update page operation when assigned.
Publish-Subscribe Pattern
The publish-subscribe pattern is one of the more common design patterns, in which there are two roles: publisher and subscriber. Multiple subscribers can subscribe to an event from the same publisher. When the event occurs, the publisher notifies all subscribers who subscribed to the event. Let’s look at an example to understand.
class Dep { constructor() { this.subs = []; } // 增加订阅者 addSub(sub) { if (this.subs.indexOf(sub) < 0) { this.subs.push(sub); } } // 通知订阅者 notify() { this.subs.forEach((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(); // 通知订阅者事件发生,触发他们的更新函数
Hands-on practice
After we understand Object.defineProperty and the publish-subscriber model, we can easily imagine that vue.js implements data monitoring based on the above two.
vue.js first uses Object.defineProperty to hijack the getters and setters of the data to be monitored. When the properties of the data are assigned/taken values, vue.js can detect it. and handle accordingly.
Through the subscription publishing model, we can create a publisher for each property of the object. When other subscribers depend on this property, the subscriber will be added to the publication. in the queue. Using the data hijacking of Object.defineProperty, when the property's setter is called, the publisher of the property notifies all subscribers of the updated content.
Next, let’s implement it (see the comments for details):
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', * age: 22, * 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) < 0) { this.subs.push(sub); } } notify() { this.subs.forEach((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; const newValue = this.get(); 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
In this way, a simple responsive data monitoring is finished. Of course, this is just a simple demo to illustrate the responsiveness principle of vue.js. The real vue.js source code will be more complicated because a lot of other logic is added.
The above is the detailed content of Detailed explanation of vue.js responsiveness principle (with code). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Guide to Table Border in HTML. Here we discuss multiple ways for defining table-border with examples of the Table Border in HTML.

Guide to HTML margin-left. Here we discuss a brief overview on HTML margin-left and its Examples along with its Code Implementation.

This is a guide to Nested Table in HTML. Here we discuss how to create a table within the table along with the respective examples.

Guide to HTML Table Layout. Here we discuss the Values of HTML Table Layout along with the examples and outputs n detail.

Guide to HTML Input Placeholder. Here we discuss the Examples of HTML Input Placeholder along with the codes and outputs.

Guide to the HTML Ordered List. Here we also discuss introduction of HTML Ordered list and types along with their example respectively

Guide to Moving Text in HTML. Here we discuss an introduction, how marquee tag work with syntax and examples to implement.

Guide to HTML onclick Button. Here we discuss their introduction, working, examples and onclick Event in various events respectively.
