ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue的双向数据绑定原理

2021-11-04 18:02:57  阅读:137  来源: 互联网

标签:node el vue 绑定 视图 双向 数据 节点


实现vue的双向数据绑定

前言

在日常生活中,很多求职者都会遇到面试问题就是vue双向数据绑定的原理。很多同学的回答大体一致:Object.defineProperty和观察者模式,再往下问就说不清楚了。接下来我会详细解析vue双向数据绑定原理,用最简单的方式给大家呈现,所以实现的过程我们会以思路为主,不会考虑更多的性能问题。

双向数据含义

  • 关于双向数据绑定,主要分为两个方向:
    1. model(数据层) --> view(视图层) 数据层改变视图层自动更新
    2. view(视图层) --> model(数据层) 视图层改变(比如input和textarea等)数据层数据也会变化
  • 对于早期框架以backbone为例来说,实现的是单向数据绑定,也就是数据层变化视图层更新,视图层变化只能通过controller(行为层,事件层)来手动修改数据。比如说用户修改了input的值,我们可以在controller层监听用户的输入事件,手动修改model层数据。目前的react个人认为应该是属于单向数据流。
  • 最早的双向数据绑定提出据我使用应该是angularJs,此处实现会再以下详细讲述,此处不做介绍。目前最火的框架vue使用的就是双向数据流。

单向数据流

  • 我们实现vue双向数据流会从单向数据流开始,实现的思路页面首次渲染绑定数据 --> 数据变化视图更新
    1. 实现首次渲染数据
      • 此处使用的是面向对象的封装模式,定义构造函数Vue,要求传入参数是一个对象,对象包含el和data两个key,el对应是根元素选择器,data对应页面渲染的数据。
      • 封装库文件vue.js
          class Vue {
              constructor (opts){
                  // 获取根元素
                  this.el = document.querySelector(opts.el)
                  // 获取数据源
                  this.data = opts.data
                  // 解析html
                  this.compile(this.el)
              }
              compile(el){
                  /* 
                      获取html里面所有的插值表达式{{}}
                      获取根元素下面所有的子节点,判断子节点的类型
                          1. 如果子节点也是一个元素节点
                              - 继续执行编译函数,找到他们下面的子节点 此处使用了递归语法
                          2. 如果子节点就是一个文本节点
                              - 判断文本节点里面是否包含插值表达式  此处使用正则表达式判断
                                  + 包含插值表达式,找到正则表达式里面的变量名
                  */
                  // 获取所有的子节点
                  let childNodes = el.childNodes
                  let reg = /\{\{(.*)\}\}/
                  childNodes.forEach(node => {
                      //  区分节点类型
                      let text = node.textContent
                      if(node.nodeType === 1){
                          // 元素节点
                          this.compile(node)
                      }else if(node.nodeType === 3 && reg.test(text)){
                          // 文本节点
                          let exp = reg.exec(text)[1]
                          console.warn('获取的变量名', exp)
                          // 渲染数据到页面
                          this.bindData(node, exp)
                      }
                  })
              }
              bindData(node, exp){
                  node.textContent = this.data[exp]
              }
          }
      
      • html使用测试
          <!-- 引入库文件 -->
          <script src="vue.js"></script>
          <!-- html结构 -->
          <div id="app">
              {{name}}
              <ul>
                  <li>{{title}}</li>
              </ul>
              <p>{{msg}}</p>
          </div>
          <!-- 创建实例 -->
          <script>
              new Vue({
                  el: "#app",
                  data: {
                      name: '张三',
                      title: '标题',
                      msg: '消息'
                  }
              })
          </script>
      

标签:node,el,vue,绑定,视图,双向,数据,节点
来源: https://www.cnblogs.com/crim/p/15509414.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有