SoFunction
Updated on 2025-04-04

Implementation method of Vue 3.0 bidirectional binding principle

proxy method

It uses data hijacking combined with publisher-subscriber mode to hijack the setters and getters of each attribute through new Proxy(), and publish messages to the subscriber when the data changes, triggering the corresponding listening callback.

The only difference between Vue 3.0 and Vue 2.0 is that the way data hijacking is changed from changing to Proxy proxy, and other code remains unchanged. Available to viewImplementation of the two-way binding principle in Vue 2.0

The specific implementation process code is as follows:

1. Define the constructor

function Vue(option){
 this.$el = (); //Get the mount node this.$data = ;
 this.$methods = ;
  = {};  //All subscriber collection Target format (one-to-many relationship): {msg: [Subscriber 1, Subscriber 2, Subscriber 3], info: [Subscriber 1, Subscriber 2]} (this.$data); //Call the observer (this.$el);  //Calling the instruction parser}

2. Define the instruction parser

 = function (el) {
 let nodes = ; //Get the child node of the mounted node for (var i = 0; i < ; i++) {
  var node = nodes[i];
  if () {
   (node) //Recursively obtain child nodes  }
  if (('l-model')) { //When there is an l-model instruction in the child node   let attrVal = ('l-model'); //Get the attribute value   ('input', (() => {
    [attrVal].push(new Watcher(node, "value", this, attrVal)); //Add a subscriber    let thisNode = node;
    return () => {
     this.$data[attrVal] =  //Update data in the data layer    }
   })())
  }
  if (('l-html')) {
   let attrVal = ('l-html'); //Get the attribute value   [attrVal].push(new Watcher(node, "innerHTML", this, attrVal)); //Add a subscriber  }
  if ((/{{([^\{|\}]+)}}/)) {
   let attrVal = (/[{{|}}]/g, ''); //Get the content of the interpolated expression   [attrVal].push(new Watcher(node, "innerHTML", this, attrVal)); //Add a subscriber  }
  if (('l-on:click')) {
   let attrVal = ('l-on:click'); //Get the method name of the event triggered   ('click', this.$methods[attrVal].bind(this.$data)); //Point this to this.$data  }
 }
}

3. Define the observer(The difference is in this piece of code)

 = function (data) {
 const that = this;
 for(var key in data){
  [key] = []; //Initialize all subscriber objects {msg: [subscriber], info: []} }
 let handler = {
  get(target, property) {
   return target[property];
  },
  set(target, key, value) {
   let res = (target, key, value);
   var watchers = [key];
   (item => {
    ();
   });
   return res;
  }
 }
 this.$data = new Proxy(data, handler);
}

4. Define subscribers

function Watcher(el, attr, vm, attrVal) {
  = el;
  = attr;
  = vm;
  = attrVal;
 (); //Update view}

5. Update the view

 = function () {
 [] = .$data[]
}

The above code is defined in a file and can be introduced where two-way binding is required.

Try using:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <script src="./"></script>
</head>
<body>
 <!--
  accomplishmvvmTwo-way binding,It is a data hijacking combined with publisher-Subscriber mode,pass()To hijack various attributessetter,getter,Post messages to subscribers when data changes,Trigger the corresponding listening callback。就必须要accomplish以下几点:
   1、accomplish一个数据监听器Observer,Ability to monitor all properties of a data object,If there is any change, you can get the latest value and notify the subscriber
   2、accomplish一个指令解析器Compile,Scan and parse instructions for each element node,Replace data according to the instruction template,And bind the corresponding update function
   3、accomplish一个Watcher,As a connectionObserverandCompileThe bridge,Ability to subscribe and receive notifications for each property change,Execute the corresponding callback function for the command binding,To update the view
   4、mvvmEntry function,Integrate the above three
 -->
 <div >
  <input type="text" l-model="msg" >
  <p l-html="msg"></p>
  <input type="text" l-model="info" >
  <p l-html="info"></p>
  <button l-on:click="clickMe">Click me</button>
  <p>{{msg}}</p>
 </div>

 <script>
  var vm = new Vue({
   el: "#app",
   data: {
    msg: "May you be happy and prosperous",
    info: "Study hard and improve every day"
   },
   methods: {
    clickMe(){
      = "I love to type code";
    }
   }
  })
 </script>
</body>
</html>

For more tutorials, click "Front-end component learning tutorial》, everyone is welcome to learn and read.

Regarding the tutorial on components, please click on the topicComponent learning tutorialCarry out learning.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.