Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of bidirectional data binding in vue2.0

2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "what is the method of vue2.0 two-way data binding". In the daily operation, I believe that many people have doubts about what the method of vue2.0 two-way data binding is. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "what is the method of vue2.0 two-way data binding?" Next, please follow the editor to study!

one。 First of all, understand what is the publish and subscribe model

Code directly: a simple publish and subscribe model to help you better understand the principle of two-way data binding

/ / publish and subscribe mode function Dep () {this.subs = [] / / Collection dependency (i.e. mobile watcher instance),} Dep.prototype.addSub = function (sub) {/ / add subscriber this.subs.push (sub) / / what is actually added is the instance of watcher} Dep.prototype.notify = function (sub) {/ / publish. The purpose of this method is to traverse the array and have each subscriber's update method execute this.subs.forEach ((sub) = > sub.update ())} function Watcher (fn) {this.fn = fn. } Watcher.prototype.update = function () {/ / add a update attribute so that each instance can inherit this method this.fn ();} let watcher = new Watcher (function () {alert (1)}); / / subscribe let dep = new Dep (); dep.addSub (watcher); / / add dependencies, add subscriber dep.notify () / / publish what did you do when you asked each subscriber's update method to execute 2.new Vue ()?

It's just an explanation for bidirectional data binding.

Value of obj.text: {{obj.text}}

Value of word: {{word}}

New Vue ({el: "# app", data: {obj: {text: "up",}, word: "Learning"}, methods: {/ /...}})

What does the Vue constructor do?

Function Vue (options = {}) {this.$options = options;// receive parameter var data = this._data = this.$options.data; observer (data); / / A pair of data feed recursive binding for (let key in data) {let val = data [key]; observer (val) Object.defineProperty (this, key, {enumerable: true, get () {return this._ data [key];}, set (newVal) {this._ data [key] = newVal;})} new Compile (options.el, this)}

In new Vue ({… }) when you construct the function, you first get the parameter options, and then assign the data data in the parameter to the _ data attribute of the current instance (this._data = this.$options.data). The point is, why is the traversal below? First of all, when we operate the data, we get it by this.word instead of this._data.word, so we do a mapping. When we get data, this.word is actually the value of the acquired this._data.word. You can output this in your own project to check it out.

1. Let's take a look at what the observer method does.

Function observer (data) {if (typeof data! = = "object") return; return new Observer (data); / / return an instance} function Observer (data) {let dep = new Dep (); / / create an dep instance for (let key in data) {/ / a pair of data is recursively bound let val = data [key]; observer (val) Object.defineProperty (data, key, {enumerable: true, get () {Dep.target & & dep.depend (Dep.target); / / Dep.target is an instance of Watcher return val;}, set (newVal) {if (newVal = = val) {return) } val = newVal; observer (newVal); dep.notify () / / Let all methods execute}})}}

The Observer constructor, first let dep=new Dep (), as the later get method and set method that triggers data hijacking, is called when collecting dependencies and publishing. The main operation is to recursively bind data data through Object.defineProperty and modify its default read and write using getter/setter to collect dependencies and publish updates.

two。 Let's take a look at exactly what Compile did.

Function Compile (el, vm) {vm.$el = document.querySelector (el); let fragment = document.createDocumentFragment (); / / create document fragments, which are object type while (child = vm.$el.firstChild) {fragment.appendChild (child);} / / use the while loop to add all the nodes to the document fragments, followed by operations on the document fragments, and finally add the document fragments to the page. A very important feature here is that if you use the appendChid method to add the nodes in the original dom tree to the fragment, the original nodes will be deleted. Replace (fragment); function replace (fragment) {Array.from (fragment.childNodes). ForEach ((node) = > {/ / Loop all nodes let text = node.textContent; let reg = /\ {(. *)\}\} / If (node.nodeType = = 3 & & reg.test (text)) {/ / determine whether the current node is a text node and whether it conforms to the output mode of {{obj.text}}. If the condition indicates that it is a two-way data binding, add a subscriber (watcher) console.log (RegExp.$1); / / obj.text let arr = RegExp.$1.split (".") / / convert to an array [obj,text]. It is convenient to take the value let val = vm; arr.forEach ((key) = > {/ / implement the value this.obj.text val = val [key];}) New Watcher (vm, RegExp.$1, function (newVal) {node.textContent = text.replace (/\ {(.*)\}\} /, newVal)}); node.textContent = text.replace (/\ {(.*)\}\} /, val) / / an assignment for initializing node content} if (node.nodeType = 1) {/ / indicates that it is an element node let nodeAttrs = node.attributes Array.from (nodeAttrs) .forEach ((item) = > {if (item.name.indexOf ("v -") > = 0) {/ / determine whether it is v-model or not the instruction node.value = vm [item.value] / a pair of node assignment operations} / / add Subscriber new Watcher (vm Item.value, function (newVal) {node.value = vm [item.value]}) Node.addEventListener ("input", function (e) {let newVal = e.target.value; vm [item.value] = newVal })})} if (node.childNodes) {/ / there are child elements in this node, and then recursive replace (node);}})} / / this is that the document in the page is gone, so you have to put the document fragments into the page vm.$el.appendChild (fragment) }

Compile (compilation method) first explains that DocuemntFragment (document fragmentation) is a dom node collection container. When you create multiple nodes, when each node is inserted into the document, it will cause a reflux, that is, the browser has to return multiple times, which consumes a lot of performance. To use document fragmentation is to put multiple nodes into a container first, and then insert the whole container directly. The browser only backflowed once.

The Compile method first traverses all the nodes of the document fragment

1. Determine whether it is a text node and whether it conforms to the output mode of {{obj.text}} double curly braces. If the condition is satisfied that it is bidirectional data binding, add watcher, new Watcher (vm, dynamically bound variable, callback function fn).

two。 Determine whether it is an element node and whether the attribute contains v-model instructions. If the condition indicates that it is a two-way data binding, add watcher, new Watcher (vm, dynamically bound variables, callback function fn) until traversal is completed. Finally, don't forget to put the document fragments on the page.

3.Dep constructor (how to collect dependencies)

Var uid=0;// publish and subscribe function Dep () {this.id=uid++; this.subs = [];} Dep.prototype.addSub = function (sub) {/ / subscribe to this.subs.push (sub); / / actually add watcher this instance} Dep.prototype.depend = function () {/ / subscription manager if (Dep.target) {/ / add Dep.target.addDep (this) when only Dep.target exists }} Dep.prototype.notify = function (sub) {/ / publish, traversing the array to have each subscriber's update method execute this.subs.forEach ((sub) = > sub.update ())}

Inside the Dep constructor, there is an id and a subs,id=uid++, id is used as the unique identity of the dep object, and subs is the array that holds the watcher. The depend method is a subscription manager, which calls the addDep method of the current watcher to add subscribers. When the get method of Object.defineProperty is triggered, Dep.target & & dep.depend (Dep.target) is called to add subscribers. When the data changes, the set method of Object.defineProperty is triggered, and the update operation of the dep.notify method is called.

What does the 4.Watcher constructor do

Function Watcher (vm, exp, fn) {this.fn = fn; this.vm = vm; this.exp = exp / / this.newDeps = []; this.depIds = new Set (); this.newDepIds = new Set (); Dep.target = this; / / this is an instance let val = vm; let arr = exp.split (".") pointing to the current (Watcher). Arr.forEach ((k) = > {/ / value this.obj.text val = val [k] / / value this.obj.text will trigger the get method of data hijacking and add the current subscriber (watcher instance) to the dependency}); Dep.target = null;} Watcher.prototype.addDep = function (dep) {var id=dep.id; if (! this.newDepIds.has (id)) {this.newDepIds.add (id) This.newDeps.push (dep); if (! this.depIds.has (id)) {dep.addSub (this);} Watcher.prototype.update = function () {/ / this is how each bound method adds a update attribute let val = this.vm; let arr = this.exp.split (".") Arr.forEach ((k) = > {val = val [k] / / value this.obj.text, passed to fn update operation}); this.fn (val); / / pass a new value}

What does the Watcher constructor do

1. Receive parameters and define several private properties (this.newDep, this.depIds,this.newDepIds)

2. Dep.target= this, perform the data value operation through the parameters, which will trigger the get method of Object.defineProperty, which will add subscribers through the subscriber manager (dep.depend ()), and then set the Dep.target=null to empty after adding.

3. The addDep on the prototype prevents subscribers from being added repeatedly through the unique identification of id and the judgment of several private attributes.

The 4.update method is that when the data is updated, dep.notify () executes, triggering the subscriber's update method, and performs the release update operation.

At this point, the study on "what is the method of vue2.0 two-way data binding" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report