vue响应式原理与双向数据的深入解析


Posted in Vue.js onJune 04, 2021

了解object.defineProperty 实现响应式

清楚 observe/watcher/dep 具体指的是什么

了解 发布订阅模式 以及其解决的具体问题

在Javascript里实现数据响应式一般有俩种方案,分别对应着vue2.x 和 vue3.x使用的方式,他们分别是:

对象属性拦截 (vue2.x) Object.defineProperty
对象整体代理 (vue3.x) Proxy

提示:以下是本篇文章正文内容,下面案例可供参考

vue-响应式是什么?

Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript对象。而当你修改它们时,视图会进行更新。这使得状态管理非常简单直接,不过理解其工作原理同样重要,这样你可以避开一些常见的问题。在这个章节,我们将研究一下

Vue 响应式系统的底层的细节。

vue-响应式如何实现的?

数据响应式:数据模型仅仅是普通的JavaScript对象,而当我们修改数据时,视图会进行更新,避免了频繁的DOM操作,提高开发效率,这与Jquery不一样,Jquery是频繁的操作Dom

对双向数据绑定的理解

数据改变,视图改变,视图改变,数据也随之改变( 通过这句话,我们可以看到在双向绑定中是包含了数据响应式的内容)

​ 我们可以使用v-model 在表单元素上创建双向数据绑定

数据驱动是Vue最独特的特性之一

​开发过程中仅仅需要关注数据本身,不需要关心数据是如何渲染到视图中的。主流的MVVM框架都已经实现了数据响应式与双向绑定,所以可以将数据绑定到DOM上。

在vue.js中,所谓的数据驱动就是当数据发生变化的时候,用户界面发生相应的变化,开发者不需要手动的去修改dom。

对数据驱动的理解:

那么vuejs是如何实现这种数据驱动的呢?

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定

将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析{{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化—>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

对vue-双向数据的分析?/v-model 双向数据绑定的原理

代码如下(示例):

<script>
    // Object 大小写 value 书写
    let data = {
      name: '李白',
      age: 18
    }

    Object.keys(data).forEach(key => {
      defineReactiveProperty(data, key, data[key])
    })

    function defineReactiveProperty(data, key, value) {
      Object.defineProperty(data, key, {
        // get获取
        get() {
          return value
        },
        // set 赋值
        set(newVaue) {
          if (newVaue === value) {
            return
          }
          value = newVaue
          compine()
        }
      })
    }
    compine()
  </script>
</body>

</html>
function compine () {
  // 通过document.querySelect('#app').childNodes 获取app下所有的子元素
  const nodes = document.querySelector('#app').childNodes
  // 输出一下这个值 当前这个值是一个层级嵌套的数组我们通过foreach 
  // console.log(nodes)

  nodes.forEach(item => {
    // 再输出一下item html:49 <input type=​"text" v-model=​"name">​ 是一个input 输入框
    // console.log(item)
    // 筛选出当前是标签的 ,因为nodes这个输出会将空格以‘text' nodeType为3,而标签nodetype是1,if判断筛选出是标签的
   if (item.nodeType === 1){
     const attrs = item.attributes
      // console.log(attrs)  {0: type, 1: v-model, type: type, v-model: v-model, length: 2} 返回了一个是数组
    Array.from(attrs).forEach( arr => {
        // console.log(arr) //  texgt= 'text' v-mode: 'name' ,筛选出这个v-model
        if (arr.nodeName === 'v-model'){
            item.value = data[arr.nodeValue]
            item.addEventListener('input',e => {
              console.log(e.target.value)
              //  
              data[arr.nodeValue] = e.target.value
            })
        }
      })
   }
  })
}

总结

vue响应式原理与双向数据的深入解析

  • 数据响应式的实现无非是对象属性拦截,我们使用 Object.defineProperty 来实现,在vue3中使
    用 Proxy 对象代理方案进行了优化
  • 面试宝典上提到的几个专业名词
    observe 对象指的是把数据处理成响应式的对象
    watcher 指的其实就是数据变化之后的更新函数 (vue中的watcher有两种,一种是用来更新视图的watcher,一种是通过watch配置项声明的watcher)
    dep 指的就是使用发布订阅实现的收集更新函数和触发更新函数的对象
  • 指令实现的核心无非是通过模板编译找到标识然后把数据绑上去,等到数据变化之后再重新放一次
  • 发布订阅模式的本质是解决一对多的问题,在vue中实现数据变化之后的精准更新

到此这篇关于vue响应式原理与双向数据的文章就介绍到这了,更多相关vue响应式原理与双向数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
springboot+vue实现文件上传下载
Nov 17 Vue.js
Vue实现手机号、验证码登录(60s禁用倒计时)
Dec 19 Vue.js
vue监听滚动事件的方法
Dec 21 Vue.js
vue导入.md文件的步骤(markdown转HTML)
Dec 31 Vue.js
vue监听键盘事件的相关总结
Jan 29 Vue.js
vue3.0封装轮播图组件的步骤
Mar 04 Vue.js
详解Vue的options
May 15 Vue.js
Vue的过滤器你真了解吗
Feb 24 Vue.js
分享一个vue实现的记事本功能案例
Apr 11 Vue.js
解决vue中provide inject的响应式监听
Apr 19 Vue.js
vue 把二维或多维数组转一维数组
Apr 24 Vue.js
vue postcss-px2rem 自适应布局
May 15 Vue.js
vue实现水波涟漪效果的点击反馈指令
vue 实现上传组件
May 31 #Vue.js
vue基于Teleport实现Modal组件
Vue+Element UI实现概要小弹窗的全过程
vue-cli4.5.x快速搭建项目
Vue CLI中模式与环境变量的深入详解
springboot+VUE实现登录注册
May 27 #Vue.js
You might like
用PHP和ACCESS写聊天室(十)
2006/10/09 PHP
PHP处理SQL脚本文件导入到MySQL的代码实例
2014/03/17 PHP
php面向对象中static静态属性与方法的内存位置分析
2015/02/08 PHP
php实现当前页面点击下载文件的实例代码
2016/11/16 PHP
完美解决thinkphp唯一索引重复时出错的问题
2017/03/31 PHP
解决出现SoapFault (looks like we got no XML document)的问题
2017/06/24 PHP
Yii1.1框架实现PHP极光推送消息通知功能
2018/09/06 PHP
Nginx+php配置文件及原理解析
2020/12/09 PHP
用Javascript 和 CSS 实现脚注(Footnote)效果
2009/09/09 Javascript
网站页面自动跳转实现方法PHP、JSP(下)
2010/08/01 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
js页面跳转的问题(跳转到父页面、最外层页面、本页面)
2013/08/14 Javascript
php中给js数组赋值方法
2014/03/10 Javascript
javascript框架设计之类工厂
2015/06/23 Javascript
分享五个有用的jquery小技巧
2015/10/08 Javascript
JS实现日期时间动态显示的方法
2015/12/07 Javascript
基于jQuery实现点击弹出层实例代码
2016/01/01 Javascript
从零学习node.js之简易的网络爬虫(四)
2017/02/22 Javascript
React入门教程之Hello World以及环境搭建详解
2017/07/11 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
Bootstrap 树控件使用经验分享(图文解说)
2017/11/06 Javascript
node.js 模块和其下载资源的镜像设置的方法
2018/09/06 Javascript
在vue中安装使用vux的教程详解
2018/09/16 Javascript
微信小程序实现时间预约功能
2018/11/27 Javascript
微信小程序自定义tabBar的踩坑实践记录
2020/11/06 Javascript
python-itchat 获取微信群用户信息的实例
2019/02/21 Python
python可视化篇之流式数据监控的实现
2019/08/07 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
Python爬虫库requests获取响应内容、响应状态码、响应头
2020/01/25 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
2020/02/09 Python
Python测试框架:pytest学习笔记
2020/10/20 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
基层工作经历证明
2014/01/13 职场文书
公安局负责人查摆问题及整改方案
2014/09/27 职场文书
2014年底个人工作总结
2015/03/10 职场文书
何时使用Map来代替普通的JS对象
2021/04/29 Javascript