Vue底层实现原理总结


Posted in Javascript onFebruary 17, 2018

前言

最近在研究 剖析Vue原理&实现双向绑定MVVM 这篇文章,一边学习一边总结一下自己的思考。

Vue是一个典型的MVVM框架,模型(Model)只是普通的JavaScript对象,修改它则视图(View)会自动更新。这种设计让状态管理变得非常简单而直观。那么Vue是如何把模型和视图建立起关联的呢?

实现原理概述

这是前言提到的文章里的代码,一段典型的体现了Vue特点的代码:

<div id="mvvm-app">
  <input type="text" v-model="word">
  <p>{{word}}</p>
  <button v-on:click="sayHi">change model</button> //点击这个button,word的值会发生改变
</div>

<script src="./js/observer.js"></script>
<script src="./js/watcher.js"></script>
<script src="./js/compile.js"></script>
<script src="./js/mvvm.js"></script>
<script>
  var vm = new MVVM({
    el: '#mvvm-app',
    data: {
      word: 'Hello World!'
    },
    methods: {
      sayHi: function() {
        this.word = 'Hi, everybody!';
      }
    }
  });
</script>

ue实现这种数据双向绑定的效果,需要三大模块:

Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者

Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数

Watcher:作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

Observer

Observer的核心是通过Obeject.defineProperty()来监听数据的变动,这个函数内部可以定义setter和getter,每当数据发生变化,就会触发setter。这时候Observer就要通知订阅者,订阅者就是Watcher。

Watcher

Watcher订阅者作为Observer和Compile之间通信的桥梁,主要做的事情是:

  1. 在自身实例化时往属性订阅器(dep)里面添加自己
  2. 自身必须有一个update()方法
  3. 待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调

Compile

Compile主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

总结

以上就是本次整理关于Vue底层实现原理的全部知识内容,如果大家还有任何不明白的地方可以在下方的留言区讨论。

Javascript 相关文章推荐
(JS实现)MapBar中坐标的加密和解密的脚本
May 16 Javascript
javascript instanceof,typeof的区别
Mar 24 Javascript
通过AJAX的JS、JQuery两种方式解析XML示例介绍
Sep 23 Javascript
js清除input中type等于file的值域(示例代码)
Dec 24 Javascript
一个css与js结合的下拉菜单支持主流浏览器
Oct 08 Javascript
JS打开新窗口防止被浏览器阻止的方法
Jan 03 Javascript
解决jquery插件:TypeError:$.browser is undefined报错的方法
Nov 21 Javascript
Angular的事件和表单详解
Dec 26 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
Jan 19 Javascript
详解js类型判断
May 22 Javascript
微信小程序通过js实现瀑布流布局详解
Aug 28 Javascript
在Vuex中Mutations修改状态操作
Jul 24 Javascript
js实现控制文件拖拽并获取拖拽内容功能
Feb 17 #Javascript
图文介绍Vue父组件向子组件传值
Feb 17 #Javascript
JavaScript异步加载问题总结
Feb 17 #Javascript
js装饰设计模式学习心得
Feb 17 #Javascript
Vue组件库发布到npm详解
Feb 17 #Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
Feb 16 #Javascript
JavaScript中严格判断NaN的方法
Feb 16 #Javascript
You might like
星际争霸, 教主第一视角, ZvT经典龙蛇演义
2020/03/02 星际争霸
apache mysql php 源码编译使用方法
2012/05/03 PHP
深入理解require与require_once与include以及include_once的区别
2013/06/05 PHP
PHP实现导出excel数据的类库用法示例
2016/10/15 PHP
PHP巧妙利用位运算实现网站权限管理的方法
2017/03/12 PHP
PHP实现登陆并抓取微信列表中最新一组微信消息的方法
2017/07/10 PHP
php魔法函数与魔法常量使用介绍
2017/07/23 PHP
PHP获取数据库表中的数据插入新的表再原删除数据方法
2018/10/12 PHP
jQuery之浮动窗口实现代码(两种方法)
2010/09/08 Javascript
IE6中使用position导致页面变形的解决方案(js代码)
2011/01/09 Javascript
弹出层之1:JQuery.Boxy (一) 使用介绍
2011/10/06 Javascript
javascript实现自动输出文本(打字特效)
2015/08/27 Javascript
基于jQuery仿淘宝产品图片放大镜特效
2020/10/19 Javascript
jQuery模拟360浏览器切屏效果幻灯片(附demo源码下载)
2016/01/29 Javascript
深入浅析knockout源码分析之订阅
2016/07/12 Javascript
学习 NodeJS 第八天:Socket 通讯实例
2016/12/21 NodeJs
js实现图片旋转 js滚动鼠标中间对图片放大缩小
2017/07/05 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
2017/07/14 Javascript
5 种JavaScript编码规范
2018/01/30 Javascript
微信小程序后端(java)开发流程的详细步骤
2019/11/13 Javascript
Javascript摸拟自由落体与上抛运动原理与实现方法详解
2020/04/08 Javascript
在项目vue中使用echarts的操作步骤
2020/09/07 Javascript
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
Python字符串逐字符或逐词反转方法
2015/05/21 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
浅谈Python实现Apriori算法介绍
2017/12/20 Python
python在线编译器的简单原理及简单实现代码
2018/02/02 Python
python 链接sqlserver 写接口实例
2020/03/11 Python
python中判断数字是否为质数的实例讲解
2020/12/06 Python
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
土木工程专业自荐信
2013/10/04 职场文书
城市规划毕业生求职信
2013/10/10 职场文书
英文求职信结束语大全
2013/10/26 职场文书
2016年公司中秋节致辞
2015/11/26 职场文书
小学科学课教学反思
2016/02/23 职场文书
大学生如何逃脱“毕业季创业队即散伙”魔咒?
2019/08/19 职场文书