一个简化版Vue助你理解Vue原理(vue 原理)

好多人看完我的这个文章对它的理解还是只是知道了大概原理,但是对具体的Vue双向绑定的实现很模糊,因此就出了这篇文章,供大家参考希望可以得到收获,以下是主要代码逻辑,先陈述一下这一过程都需要什么:

需要有一个接收Vue实例配置项的构造函数SimpleVue,给他加两个原型方法分别是observe()和compile(),再构造出一个订阅器watcher,给他加一个更新视图方法

  • observe():用来劫持并监听数据变化的数据监听器,有变化就会通知下文中的订阅器watcher
  • compile():节点DOM解析器,用来获取和解析每一个节点及其指令,根据初始化的模板数据来创建订阅器watcher
  • watcher():订阅器watcher,用来接收属性值的相关数据的变化通知,调用自身原型方法update从而更新视图

由于Vue就是一个MVVM的框架理念,所以就要通过Object.defineProperty()方法来劫持并监听所有属性值相关的数据,看看它是否变化,如有变化则通知订阅器watcher看是否需要视图更新,这一过程就是我们的数据监听器observe的工作任务,由于数据和订阅器是一对多的关系,所以通知订阅器的时候需要把数据对应的订阅器的集合都放在一个oWatcherObj对象中,接下来需要一个节点DOM解析器compile,主要用来迭代递归获取和解析每一个节点及其指令,根据初始化的模板数据来创建订阅器watcher,实例化watcher就会接到数据变化的通知,进而实现VM更新视图

template:

<div id=\”simpleVue\”>

<button yf-on:click=\”copy\”>戳我</button>

<div>

<textarea yf-model=\”name\”></textarea>

<div yf-text=\”name\”></div>

</div>

<hr>

<button yf-on:click=\”show\”>显示/隐藏</button>

<div yf-if=\”isShow\”>

<input type=\”text\” yf-model=\”webSite\”>

<div yf-text=\”webSite\”></div>

</div>

</div>

SimpleVue构造:

class SimpleVue { // 简化版Vue实例的构造 用来接收实例的配置项

constructor(options) {

this.$el = document.querySelector(options.el);

this.$data = options.data;

this.$methods = options.methods;

this.oWatcherObj = {}; // 所有属性值相关的数据对应的订阅器的集合都放在该对象中

this.observe(); // 调用数据监听器对属性值相关的数据进行劫持并监听

this.compile(this.$el); // 对该DOM节点进行解析

}

observe() { // 数据监听器 用来劫持并监听属性值相关数据的变化 如有变化则通知订阅器watcher

for (let key in this.$data) {

let value = this.$data[key];

this.oWatcherObj[key] = []; // 初始化该数据的订阅器 数据和订阅器的关系是一对多

let oWatcherObj = this.oWatcherObj[key];

Object.defineProperty(this.$data, key, { // 关键方法 可以修改对象身上的默认属性值的ES5方法 下面用到的是ES中两大属性中的访问器属性,有以下四种描述符对象

configurable: false, // 该状态下的属性描述符不能被修改和删除

enumerable: false, // 该状态下的属性描述符中的属性不可被枚举

get() { // 属性值相关的数据读取函数

return value;

},

set(newVal) { // 属性值相关的数据写入函数

if (newVal !== value) {

value = newVal;

oWatcherObj.forEach((obj) => {

obj.update(); // 通知和该数据相关的所有订阅器

});

}

}

});

}

}

compile(el) { // 节点DOM解析器 用来获取和解析每一个节点及其指令 根据初始化的模板数据来创建订阅器watcher

let nodes = el.children;

for (let i = 0; i < nodes.length; i ) { // 迭代同级所有节点

let node = nodes[i];

if (node.children.length > 0) {

this.compile(node); // 递归所有子节点

}

if (node.hasAttribute(\’yf-on:click\’)) { // 节点中如存在该指令则执行以下操作

let eventAttrVal = node.getAttribute(\’yf-on:click\’);

node.addEventListener(\’click\’, this.$methods[eventAttrVal].bind(this.$data)); // 绑定获取到的指令对应的数据所触发的方法

}

if (node.hasAttribute(\’yf-if\’)) {

let ifAttrVal = node.getAttribute(\’yf-if\’);

this.oWatcherObj[ifAttrVal].push(new Watcher(this, node, \”\”, ifAttrVal)); // 给该指令对应的数据创建订阅器放在该数据对应的订阅器数组里

}

if (node.hasAttribute(\’yf-model\’)) {

let modelAttrVal = node.getAttribute(\’yf-model\’);

node.addEventListener(\’input\’, ((i) => { // 前方高能:此处有闭包请绕行!!! i的问题

this.oWatcherObj[modelAttrVal].push(new Watcher(this, node, \”value\”, modelAttrVal));

return () => {

this.$data[modelAttrVal] = nodes[i].value; // 将该指令所在节点的值扔给该指令的数据

}

})(i));

}

if (node.hasAttribute(\’yf-text\’)) {

let textAttrVal = node.getAttribute(\’yf-text\’);

this.oWatcherObj[textAttrVal].push(new Watcher(this, node, \”innerText\”, textAttrVal));

}

}

}

}

订阅器构造:

class Watcher { // 订阅器构造 用来接收属性值的相关数据的变化通知 从而更新视图

constructor(…arg) {

this.vm = arg[0];

this.el = arg[1];

this.attr = arg[2];

this.val = arg[3];

this.update(); // 初始化订阅器时更新一下视图

}

update() { // 将收到的新的数据更新在视图中从而实现真正的VM

if (this.vm.$data[this.val] === true) {

this.el.style.display = \’block\’;

} else if (this.vm.$data[this.val] === false) {

this.el.style.display = \’none\’;

} else {

this.el[this.attr] = this.vm.$data[this.val];

}

}

}

Shortcuts

  • 戳我运行代码
  • Edit on GitHub
  • Try in JSFiddle

希望大家阅读完本文可以有所收获,因为能力有限,掌握的知识也是不够全面,欢迎大家提出来一起分享!谢谢O(∩_∩)O~

一个简化版Vue助你理解Vue原理(vue 原理)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2024年7月5日 下午2:05
下一篇 2024年7月5日 下午2:17

相关推荐

  • 交通工程 软件(交通工程管理软件)

    交通工程管理软件介绍 交通工程管理软件是一种用于交通工程领域的计算机软件,可以帮助交通工程师进行交通规划,设计,施工和管理。随着交通工程领域的迅速发展,交通工程管理软件已经成为交通…

    科研百科 2024年8月26日
    26
  • 图书馆科研课题立项捷报频传(图书馆科研项目)

    3月31日下午,湖北省图书学会发布科研项目立项通知,至此武汉工程大学图书馆2022年项目申报结果全部揭晓,图书馆科研项目立项捷报频传。 2022年图书馆项目申报取得了亮眼的成绩:中…

    科研百科 2024年4月13日
    56
  • 智慧工地管理系统_鹏业智慧工地系统(鹏业智慧工地平台)

    塔吊安全管理系统 管理应用场景是集互联网技术、传感器技术、嵌入式技术、数据采集储存技术、数据库技术等高科技应用技术为一体的综合性黑匣子。实现多方实时监管、区域防碰撞、塔群防碰撞、防…

    科研百科 2024年4月23日
    54
  • 企业研究开发项目管理系统的意义(企业研究开发项目管理系统)

    企业研究开发项目管理系统企业研究开发项目管理系统是企业管理和企业战略开发的主要方式。包括企业企业管理、企业战略管理等领域。不同的企业管理体系是不同的,根据我国战略和人才战略的不同,…

    科研百科 2024年5月17日
    55
  • 落实“六个一”,激活“党建+微网格”工作实效(党建引领微网格)

    红网时刻通讯员 罗亚玲 长沙报道 “我想反映个问题,合兴组大浏高速下垄,排水沟阻塞比较严重,耕地无法排灌,希望能帮忙解决下。”4月6日晚,在浏阳市花园村大屋组的户主会议上,村民在“…

    科研百科 2023年1月27日
    93
  • 微信小程序地图api开发文档

    微信小程序地图API开发文档 随着微信小程序的不断发展,地图 API 已经成为了微信小程序中不可或缺的一部分。它提供了丰富的地图数据和功能,可以帮助开发者快速构建地图应用程序。本文…

    科研百科 2024年10月9日
    11
  • 1570mpa相当于1570Nmm

    1570mpa相当于1570N/mm 材料强度是评估材料强度的重要指标,其中帕斯卡(Pa)是常用的强度单位,而牛顿每毫米(N/mm)则是常用的材料力学强度单位。在材料强度的计算中,…

    科研百科 2024年11月28日
    0
  • 科研项目所处阶段

    科研项目所处阶段:探索阶段 随着科技的不断发展,科研项目也在不断推进。目前,我们的科研项目正处于探索阶段,这是一个非常具有挑战性的阶段。在这个阶段,我们的任务是探索新的研究方向,并…

    科研百科 2024年10月21日
    0
  • 康复科设有科研项目吗为什么康复科设有科研项目吗为什么

    康复科为什么要设有科研项目? 康复科作为医院的一个重要科室,其目的是帮助患者恢复身体健康,并促进他们的康复。科研项目是康复科实现这一目标的重要手段之一。下面,我们将探讨为什么康复科…

    科研百科 2024年6月12日
    30
  • 重点科研项目合作

    重点科研项目合作 近年来,随着科技的不断发展,科研项目合作已成为学术界和工业界共同关注的热点话题。在科技创新的旅途中,合作是推动进程的关键力量。因此,如何有效地进行科研项目合作,已…

    科研百科 2025年2月21日
    1