Maison > interface Web > Voir.js > Vous apprendre étape par étape comment implémenter une liaison bidirectionnelle vue

Vous apprendre étape par étape comment implémenter une liaison bidirectionnelle vue

青灯夜游
Libérer: 2022-03-03 19:41:26
avant
3391 Les gens l'ont consulté

Comment implémenter la liaison bidirectionnelle dans vue ? Cet article vous apprendra étape par étape comment rédiger une reliure bidirectionnelle vue, afin que tout le monde puisse mieux comprendre la direction logique de la reliure bidirectionnelle. J'espère que cela sera utile à tout le monde !

Vous apprendre étape par étape comment implémenter une liaison bidirectionnelle vue

Cet article est principalement un processus d'écriture des pièges et de remplissage des pièges, permettant au public de mieux comprendre comment mettre en œuvre la liaison bidirectionnelle et la direction logique de la liaison bidirectionnelle. À ce stade, nous mettrons en œuvre une liaison bidirectionnelle. -liaison étape par étape. Il s'agit d'un article de didacticiel de classe. Tant que vous suivez l'article et observez attentivement chaque classe, ce n'est pas difficile à mettre en œuvre.

Démarrer

Démarrer Mage ? Amenez un chien ! !

Cela ne semble pas correct

Commencez avec une image

Vous apprendre étape par étape comment implémenter une liaison bidirectionnelle vue

Vous pouvez voir sur l'image que la nouvelle Vue() est divisée en deux étapesnew Vue()分为了两步走

  • 代理监听所有数据,并与Dep进行关联,通过Dep通知订阅者进行视图更新。【相关推荐:vuejs视频教程

  • 解析所有模板,并将模板中所用到的数据进行订阅,并绑定一个更新函数,数据发生改变时Dep通知订阅者执行更新函数。

接下里就是分析如何去实现,并且都需要写什么,先看一段vue的基础代码,我们从头开始分析

<div id="app">
  <input v-model="message" />
  <p>{{message}}</p>
</div>
Copier après la connexion
let app = new Vue({
    el:"#app",
    data:{
      message:"测试这是一个内容"
    }
})
Copier après la connexion

从上面代码我们可以看到new Vue的操作,里面携带了eldata属性,这算是最基础的属性,而在html代码中我们知道<div id="app">是vue渲染的模板根节点,所以vue要渲染页面就要去实现一个模板解析的方法Compile类,解析方法中还需要去处理{{ }}v-model两个指令,除了解析模板之后我们还需要去实现数据代理也就是实现Observer

实现 Vue 类

如下代码所示,这就写完了Vue类,够简单吧,如果对class关键字不熟悉的,建议先去学习一下,从下面我们可能看到,这里实例化了两个类,一个是代理数据的类,一个是解析模板的类。

class Vue {
  constructor(options) {
    // 代理数据
    new Observer(options.data)
    // 绑定数据
    this.data = options.data
    // 解析模板
    new Compile(options.el, this)
  }
}
Copier après la connexion

接着往下我们先写一个Compile类用于解析模板,我们再来分析一波,解析模板要做什么事

  • 我们要解析模板不可能直接对dom继续操作,所以我们要创建一个文档片段(虚拟dom),然后将模板DOM节点复制一份到虚拟DOM节点中,对虚拟DOM节点解析完成之后,再将虚拟DOM节点替换掉原来的DOM节点

  • 虚拟节点复制出来之后,我们要遍历整个节点树进行解析,解析过程中会对DOM的atrr属性进行遍历找到Vue相关的指令,除此之外还要对 textContent节点内容进行解析,判断是否存在双花括号

  • 将解析出来所用到的属性进行一个订阅

实现模板解析 Compile 类

下面我们将逐步实现

  • 构建Compile类,先把静态节点和Vue实例获取出来,再定义一个虚拟dom的属性用来存储虚拟dom

class Compile {
  constructor(el, vm) {
    // 获取静态节点
    this.el = document.querySelector(el);
    // vue实例
    this.vm = vm 
    // 虚拟dom
    this.fragment = null 
    // 初始化方法
    this.init()
  }
}
Copier après la connexion
  • 实现初始化方法init(),该方法主要是用于创建虚拟dom和调用解析模板的方法,解析完成之后再将DOM节点替换到页面中

class Compile { 
  //...省略其他代码

  init() {
    // 创建一个新的空白的文档片段(虚拟dom)
    this.fragment = document.createDocumentFragment()
  	// 遍历所有子节点加入到虚拟dom中
    Array.from(this.el.children).forEach(child => {
      this.fragment.appendChild(child)
    })
    // 解析模板
    this.parseTemplate(this.fragment)
    // 解析完成添加到页面
    this.el.appendChild(this.fragment);
  }
}
Copier après la connexion
  • 实现解析模板方法parseTemplate,主要是遍历虚拟DOM中的所有子节点并进行解析,根据子节点类型进行不同的处理。

class Compile { 
  //...省略其他代码

  // 解析模板 
  parseTemplate(fragment) {
    // 获取虚拟DOM的子节点
    let childNodes = fragment.childNodes || []
    // 遍历节点
    childNodes.forEach((node) => {
      // 匹配大括号正则表达式 
      var reg = /\{\{(.*)\}\}/;
      // 获取节点文本
      var text = node.textContent;
      if (this.isElementNode(node)) { // 判断是否是html元素
        // 解析html元素
        this.parseHtml(node)
      } else if (this.isTextNode(node) && reg.test(text)) { //判断是否文本节点并带有双花括号
        // 解析文本
        this.parseText(node, reg.exec(text)[1])
      }

      // 递归解析,如果还有子元素则继续解析
      if (node.childNodes && node.childNodes.length != 0) {
        this.parseTemplate(node)
      }
    });
  }
}
Copier après la connexion
  • 根据上面的代码我们得出需要实现两个简单的判断,也就是判断是否是html元素和文字元素,这里通过获取nodeType的值来进行区分,不了解的可以直接看一下 传送门:Node.nodeType,这里还扩展了一个isVueTag方法,用于后面的代码中使用

class Compile { 
  //...省略其他代码

	// 判断是否携带 v-
  isVueTag(attrName) {
    return attrName.indexOf("v-") == 0
  }
  // 判断是否是html元素
  isElementNode(node) {
    return node.nodeType == 1;
  }
  // 判断是否是文字元素
  isTextNode(node) {
    return node.nodeType == 3;
  }
}
Copier après la connexion
Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Tutoriels associés
Recommandations populaires
Derniers cours
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal