This is the 22nd day of my participation in the First Challenge 2022

1. Realize one-way data binding from data to view

  1. Setter functions for data hijacking are first triggered when data changes
  set(newVal) {
    value = newVal
    Observe(value)
    // Notify each subscriber to update his own text
    dep.notify()
  }
Copy the code

The setter function changes the new value and then notifies each subscriber.

  1. The notify function of the Dep class notifies each subscriber watcher
  notify() {
    this.subs.forEach(watcher= > watcher.update())
  }
Copy the code
  1. The Update function of the Watcher class gets the latest value and calls the render function.
  update() {
    const value = this.key.split('. ').reduce((newObj,k) = > newObj[k],this.vm)
    this.cb(value);
  }
Copy the code
  1. The render function performs rendering
new Watcher(vm,execResult[1].(newValue) = > {
  node.textContent = text.replace(regMustache,newValue);
})
Copy the code

Two, the realization of text box one-way data binding

In the rendering function, we first determine whether the current node is input and contains the attribute V-model. If so, we get the value and create watcher instance.

// Check whether the current node is an input box
if (node.nodeType === 1 && node.tagName.toUpperCase() === 'INPUT') {
  // Get all the attribute nodes of the current element
  const attrs = Array.from(node.attributes);
  const findResult = attrs.find(x= > x.name === 'v-model')
  if (findResult) {
    V-model ="name" v-model="info.a"
    const expStr = findResult.value;
    const value = expStr.split('. ').reduce((newObj,k) = > newObj[k],vm);
    node.value = value;
    // Create a Watcher instance
    new Watcher(vm,expStr,(newValue) = >{ node.value = newValue; }}})Copy the code

Realize bidirectional data binding of text box

The key to realize bidirectional data binding of text box is to monitor the input event of text box, get the latest value of text box, and update the latest value to VM on the basis of one-way data binding.

// Check whether the current node is an input box
if (node.nodeType === 1 && node.tagName.toUpperCase() === 'INPUT') {
  // Get all the attribute nodes of the current element
  const attrs = Array.from(node.attributes);
  const findResult = attrs.find(x= > x.name === 'v-model')
  if (findResult) {
    V-model ="name" v-model="info.a"
    const expStr = findResult.value;
    const value = expStr.split('. ').reduce((newObj,k) = > newObj[k],vm);
    node.value = value;
    // Create a Watcher instance
    new Watcher(vm,expStr,(newValue) = > {
      node.value = newValue;
    })

    // Listen for the input event of the text box, get the latest value of the text box, and update the latest value to the VM
    node.addEventListener('input'.e= > {
      const keyArr = expStr.split('. ');
      const obj = keyArr.slice(0,keyArr.length-1).reduce((newObj,k) = > newObj[k],vm);
      obj[keyArr[keyArr.length - 1]] = e.target.value; }}})Copy the code

conclusion

Vue two-way data binding is the embodiment of data hijacking, template compilation, publish and subscribe mode and other comprehensive knowledge points, which we must learn and master.