A brief discussion on the principle of Vue data responsiveness
This article mainly introduces a brief discussion on the principle of Vue data responsiveness, which has certain reference value. Now I share it with you. Friends in need can refer to it
Preface
Vue's data response mainly relies on Object.defineProperty(), so what is the whole process like? Taking the path of Vue with our own ideas actually means taking the principles of Vue as the end point. Let's reverse the implementation process.
The codes in this article are all low-configuration versions, and many places are not rigorous. For example, if(typeof obj === 'object') is to determine whether obj is an object, although obj may also be an array, etc. Other types of data, but for the sake of simplicity, this article will write it directly to represent the judgment object. For arrays, use Array.isArray().
Transform data
Let’s first try to write a function for transforming objects:
Why should we write this first? What about functions? Because transforming data is the most basic and important step, all subsequent steps will depend on this step.
// 代码 1.1 function defineReactive (obj,key,val) { Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get: function () { return val; }, set: function (newVal) { //判断新值与旧值是否相等 //判断的后半段是为了验证新值与旧值都为NaN的情况 NaN不等于自身 if(newVal === val || (newVal !== newVal && value !== value)){ return ; } val = newVal; } }); }
For example, const obj = {}, and then call the defineReactive(obj,'a',2) method. At this time, within the function, val=2 , then every time you get the value of obj.a, you get the value of val, and when you set obj.a, you also set the value of val. (Every call to defineReactive will generate a closure to save the value of val);
Process Discussion
After verification, I found that this function can indeed be used. Then let’s discuss the response process:
Input data
Transform data (defineReactive() )
If the data changes=> trigger event
Let’s look at the third step. How does the data change trigger subsequent events? Think about it carefully, if you want to change the data, you must set the data first, then we can just add the method to set() and it will be ok.
Then there is another important question:
Dependency Collection
How do we know what event will be triggered after the data changes? In Vue:
Use data => View; Data is used to render the view, so it is the best time to collect dependencies when obtaining data. Vue generates a Dep instance, used to collect dependencies.
// 代码 1.2 class Dep { constructor(){ //订阅的信息 this.subs = []; } addSub(sub){ this.subs.push(sub); } removeSub (sub) { remove(this.subs, sub); } //此方法的作用等同于 this.subs.push(Watcher); depend(){ if (Dep.target) { Dep.target.addDep(this); } } //这个方法就是发布通知了 告诉你 有改变啦 notify(){ const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update(); } } } Dep.target = null;
Code 1.2 is part of the code of Dep. For the time being, you only need to know the functions of 2 methods
depend() --- It can be understood as collecting dependent events. Without considering other aspects, the function is equivalent to addSub()
notify() --- This method is more For clarity, execute the update() method of all dependencies. Just change the view later and so on.
This article mainly discusses the process of data response and does not discuss the Watcher class in depth, so you only need to know the functions of the methods in Dep.
Then it’s time to change the code 1.1
//代码 1.3 function defineReactive (obj,key,val) { const dep = new Dep(); Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get: function () { if(Dep.target){ //收集依赖 等同于 dep.addSub(Dep.target) dep.depend() } return val; }, set: function (newVal) { if(newVal === val || (newVal !== newVal && val !== val)){ return ; } val = newVal; //发布改变 dep.notify(); } }); }
There is a doubt in this code, what is Dep.target? Why do we need Dep.target to collect dependencies?
Dep is a class, and Dep.target is an attribute of the class, not an attribute of the dep instance.
The Dep class is available globally, so Dep.target can be accessed globally and its value can be changed arbitrarily.
get This method is very common to use, and it is impossible to call dep.depend() every time you use it to obtain data values.
dep.depend() is actually dep.addSub(Dep.target).
The best way is to set Dep.target to an object before use, and set Dep.target = null after the subscription is completed.
Verification
It’s time to verify the availability of a wave of codes
//代码 1.4 const obj = {};//这一句是不是感觉很熟悉 就相当于初始化vue的data ---- data:{obj:{}}; //低配的不能再低配的watcher对象(源码中是一个类,我这用一个对象代替了) const watcher = { addDep:function (dep) { dep.addSub(this); }, update:function(){ html(); } } //假装这个是渲染页面的 function html () { document.querySelector('body').innerHTML = obj.html; } defineReactive(obj,'html','how are you');//定义响应式的数据 Dep.target = watcher; html();//第一次渲染界面 Dep.target = null;
The interface on the browser is like this
Then open the console below to start debugging, enter:
obj.html = 'I am fine thank you'
Then I discovered that the moment I pressed Enter, a miracle happened and the page became
End
The design pattern of Vue data response is somewhat similar to the subscription publishing pattern, but different. Each dep instance is a subscription. Center, every publication will publish all subscriptions.
There is actually a large part of Vue's responsiveness principle. This article mainly discusses how Vue allows data to respond. But in fact, there is generally a lot of data. One data is used in many places. Observe after changing the data. New values, how to observe, how to subscribe, how to schedule, there are still a lot of things that have not been discussed. The three main classes, Dep (collecting dependencies), Observer (observing data), and Watcher (subscribers, notifying subscribers if data changes), have only been mentioned a little bit.
I previously wrote an article about Vue responsiveness - array mutation method, which discusses the transformation of arrays in Vue. Of course, there will be more other articles later, and there is still a lot of content in the entire data response process, and the three main classes have not been discussed yet.
In fact, reading the source code is not only to know how the source code works, but more importantly, to learn the author’s ideas and methods. The articles I write are not long, and I hope that I can focus on one point at a time. , can truly understand the principle of this point. Of course, I also want to control the reading time so that people don’t close it after reading it halfway through.
Related recommendations:
Summary of vue data transfer methods
##Detailed explanation of vue data transfer implementation steps
Usage of Vue data listening method watch
The above is the detailed content of A brief discussion on the principle of Vue data responsiveness. For more information, please follow other related articles on the PHP Chinese website!

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.


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

SublimeText3 English version
Recommended: Win version, supports code prompts!

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

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

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Atom editor mac version download
The most popular open source editor