Vue.js实现数据响应的方法


Posted in Javascript onAugust 13, 2018

许多前端JavaScript框架(例如Angular,React和Vue)都有自己的数据相应引擎。通过了解相应性及其工作原理,您可以提高开发技能并更有效地使用JavaScript框架。在视频和下面的文章中,我们构建了您在Vue源代码中看到的相同类型的Reactivity。

如果您观看此视频而不是阅读文章,请观看系列中的下一个视频,与Vue的创建者Evan You讨论反应性和代理。

? The Reactivity System

当你第一次看到它时,Vue的响应系统看起来很神奇。拿这个简单的Vue应用程序:

Vue.js实现数据响应的方法

Vue.js实现数据响应的方法

不知何故,Vue只知道如果价格发生变化,它应该做三件事:

  • 更新我们网页上的价格值。
  • 重新计算乘以price * quantity的表达式,并更新页面。
  • 再次调用totalPriceWithTax函数并更新页面。

但是等等,你应该会觉得奇怪,当价格变化时,Vue如何知道要更新什么,以及它如何跟踪所有内容?

Vue.js实现数据响应的方法

这不是JavaScript编程常规的工作方式。

如果你不明白,那我们试着看看常规的JavaScript是怎么运行的。例如,如果我运行此代码:

Vue.js实现数据响应的方法

你觉得它打印什么?由于我们没有使用Vue,它将打印10。

Vue.js实现数据响应的方法

在Vue,我们希望每当价格或数量更新时,总计都会得到更新。我们想要:

Vue.js实现数据响应的方法

不幸的是,JavaScript是程序性的,而不是被动的,所以这在现实生活中不起作用。为了使数据变化得到相应,我们必须使用JavaScript来使事情表现不同。

⚠️ 问题

我们需要保存计算总数的方式,以便在价格或数量变化时重新运行。

✅ 解决方案

首先,我们需要一些方法告诉我们的应用程序,“我即将运行的代码,存储它,我可能需要你在另一个时间运行它。”然后我们将要运行代码,如果价格或数量变量得到更新,再次运行存储的代码。

Vue.js实现数据响应的方法

请注意,我们在目标变量中存储了一个匿名函数,然后调用了一个记录函数。使用ES6箭头语法我也可以这样写:

Vue.js实现数据响应的方法

请注意,我们在目标变量中存储了一个匿名函数,然后调用了一个记录函数。使用ES6箭头语法我也可以这样写:

Vue.js实现数据响应的方法

记录的方法:

Vue.js实现数据响应的方法

我们正在存储目标(在我们的例子中是{total = price * quantity}),所以我们可以稍后运行它。

Vue.js实现数据响应的方法

这将遍历存储阵列中存储的所有匿名函数并执行它们中的每一个。

然后在我们的代码中,我们可以:

Vue.js实现数据响应的方法

很简单吧?如果您需要阅读并尝试再次掌握它,这里的代码就完整了。仅供参考,如果您想知道原因,我会以特定的方式对此进行编码。

Vue.js实现数据响应的方法

Vue.js实现数据响应的方法

⚠️ 问题

我们可以根据需要继续记录目标,但是有一个更强大的解决方案可以扩展我们的应用程序。那就是一个负责维护目标列表的类,当我们需要它们重新运行时,这些目标列表会得到通知。

✅ 解决方法: 使用Class

我们可以开始解决这个问题的一种方法是将这种行为封装到它自己的Class中,这是一个实现标准编程观察者模式的依赖类。

因此,如果我们创建一个JavaScript类来管理我们的依赖项(它更接近Vue处理事物的方式),它可能看起来像这样:

Vue.js实现数据响应的方法

让它运行:

Vue.js实现数据响应的方法

它仍然有效,现在我们的代码感觉更可靠了。只有仍然感觉有点奇怪的是target()的设置和运行。

⚠️ 问题

我们将为每个变量设置一个Dep类,并且很好地封装了创建需要监视更新的匿名函数的行为。也许观察者功能可能是为了处理这种行为。

Vue.js实现数据响应的方法

(这只是上面的代码)

我们可以改为:

Vue.js实现数据响应的方法

✅ 解决方案:观察者功能

在我们的Watcher功能中,我们可以做一些简单的事情:

Vue.js实现数据响应的方法

如您所见,watcher函数接受myFunc参数,将其设置为我们的全局目标属性,调用dep.depend()以将目标添加为订阅者,调用目标函数并重置目标。

现在,当我们运行以下内容时:

Vue.js实现数据响应的方法

Vue.js实现数据响应的方法

您可能想知道为什么我们将target实现为全局变量,而不是将其传递到我们需要的函数中。这有一个很好的理由,这将在我们的文章结尾处揭晓。

⚠️ 问题

我们有一个Dep类,但我们真正想要的是每个变量都有自己的Dep。在我们继续之前,先存储一下数据。

Vue.js实现数据响应的方法

让我们假设我们的每个属性(价格和数量)都有自己的内部Dep类。

Vue.js实现数据响应的方法

当我们运行时:

Vue.js实现数据响应的方法

由于访问了data.price值,我希望price属性的Dep类将我们的匿名函数(存储在目标中)推送到其订阅者数组(通过调用dep.depend())。由于访问了data.quantity,我还希望quantity属性Dep类将此匿名函数(存储在目标中)推送到其订阅者数组中。

Vue.js实现数据响应的方法

如果我有另一个匿名函数,只访问data.price,我希望只推送到价格属性Dep类。

Vue.js实现数据响应的方法

我什么时候想要在价格订阅者上调用dep.notify()?我希望在设定价格时调用它们。在文章的最后,我希望能够进入控制台并执行:

Vue.js实现数据响应的方法

我们需要一些方法来挂钩数据属性(如价格或数量),所以当它被访问时我们可以将目标保存到我们的订阅者数组中,当它被更改时,运行存储在我们的订阅者数组中的函数。

✅ 解决方案:Object.defineProperty()

我们需要了解Object.defineProperty()函数,它是简单的ES5 JavaScript。它允许我们为属性定义getter和setter函数。在我向您展示如何在Dep类中使用它之前,先简单展示一下改函数的用法。

Vue.js实现数据响应的方法

Vue.js实现数据响应的方法

如您所见,它只记录两行。但是,它实际上并没有获取或设置任何值,因为我们过度使用了该功能。我们现在加回来吧。 get()期望返回一个值,而set()仍然需要更新一个值,所以让我们添加一个internalValue变量来存储我们当前的价格值。

Vue.js实现数据响应的方法

既然我们的get和set工作正常,您认为将打印到控制台的是什么?

Vue.js实现数据响应的方法

因此,当我们获取并设置值时,我们可以获得通知。通过一些递归,我们可以为数组中的所有项运行它

FYI,Object.keys(data)返回对象键的数组。

Vue.js实现数据响应的方法

现在一切都有getter和setter,我们在控制台上看到了这一点。

Vue.js实现数据响应的方法

? Putting both ideas together

Vue.js实现数据响应的方法

当像这样的一段代码运行并获得价格的价值时,我们希望价格记住这个匿名函数(目标)。这样,如果价格变化,或者设置为新值,它将触发此函数以重新运行,因为它知道此行依赖于它。所以你可以这样想。

Get =>记住这个匿名函数,当我们的值发生变化时,我们会再次运行它。

Set =>运行保存的匿名函数,我们的值刚改变。

或者就我们的Dep Class而言

Price accessed (get) => 调用dep.depend()来保存当前目标

Price set => 在价格上调用dep.notify(),重新运行所有目标

让我们结合这两个想法,并完成我们的最终代码。

Vue.js实现数据响应的方法

现在看看会发生什么。

Vue.js实现数据响应的方法

正是我们所希望的!价格和数量都确实是得到了实时的响应的!只要价格或数量的价值得到更新,我们的总代码就会重新运行。

Vue文档中的这个插图现在应该开始有意义了。

Vue.js实现数据响应的方法

你看到那个漂亮的紫色数据圈了吗?看起来应该很眼熟!每个组件实例都有一个从getter(红线)收集依赖项的服务观察器实例(蓝色)。当稍后调用设置程序时,它会通知监视程序,它将导致组件重新呈现。下面是我自己的一些注释的图片。

Vue.js实现数据响应的方法

是的,现在是不是觉得更有意义了。

显然,Vue做的可能更复杂更惊喜,但你现在知道了基础知识。

⏪ 总结:所以我们学了什么?如何创建一个Dep类来收集依赖项(依赖)并重新运行所有依赖项(notify)。如何创建一个观察程序来管理我们正在运行的代码,这些代码可能需要作为依赖项添加(target)。如何使用Object.defineProperty()创建getter和setter。

总结

以上所述是小编给大家介绍的Vue.js实现数据响应的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Iframe自适应高度绝对好使的代码 兼容IE,遨游,火狐
Jan 27 Javascript
19个很有用的 JavaScript库推荐
Jun 27 Javascript
编写针对IE的JS代码两种编写方法
Jan 30 Javascript
『jQuery』.html(),.text()和.val()的概述及使用
Apr 22 Javascript
javascript中interval与setTimeOut的区别示例介绍
Mar 14 Javascript
js拆分字符串并将分割的数据放到数组中的方法
May 06 Javascript
Angularjs全局变量被作用域监听的正确姿势
Feb 06 Javascript
jquery tmpl模板(实例讲解)
Sep 02 jQuery
JS实现数组去重,显示重复元素及个数的方法示例
Jan 21 Javascript
element-ui上传一张图片后隐藏上传按钮功能
May 22 Javascript
JavaScript进阶(三)闭包原理与用法详解
May 09 Javascript
使用vuex-persistedstate本地存储vuex
Apr 29 Vue.js
jQuery模拟12306城市选择框功能简单实现方法示例
Aug 13 #jQuery
Bootstrap Table实现定时刷新数据的方法
Aug 13 #Javascript
angular2实现统一的http请求头方法
Aug 13 #Javascript
AngularJS发送异步Get/Post请求方法
Aug 13 #Javascript
vue后台管理之动态加载路由的方法
Aug 13 #Javascript
jQuery中$原理实例分析
Aug 13 #jQuery
Angular服务Request异步请求的实例讲解
Aug 13 #Javascript
You might like
用PHP即时捕捉PHP中的错误并发送email通知的实现代码
2013/01/19 PHP
Fatal error: session_start(): Failed to initialize storage module: files问题解决方法
2014/05/04 PHP
PHP查看SSL证书信息的方法
2016/09/22 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
jquery统计输入文字的个数并对其进行判断
2014/01/07 Javascript
JS实现队列与堆栈的方法
2016/04/21 Javascript
JavaScript数据类型转换的注意事项
2016/07/31 Javascript
angularjs实现文字上下无缝滚动特效代码
2016/09/04 Javascript
js实现canvas保存图片为png格式并下载到本地的方法
2017/08/31 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
2018/06/20 jQuery
js+html实现周岁年龄计算器
2019/06/25 Javascript
微信小程序监听用户登录事件的实现方法
2019/11/11 Javascript
详解微信小程序工程化探索之webpack实战
2020/04/20 Javascript
0基础学习前端开发的一些建议
2020/07/14 Javascript
Javascript call及apply应用场景及实例
2020/08/26 Javascript
[16:04]DOTA2海涛带你玩炸弹 9月5日更新内容详解
2014/09/05 DOTA
[01:20]DOTA2 齐天大圣至宝动态展示
2016/12/13 DOTA
Python实现在线暴力破解邮箱账号密码功能示例【测试可用】
2017/09/06 Python
python实现WebSocket服务端过程解析
2019/10/18 Python
python定间隔取点(np.linspace)的实现
2019/11/27 Python
python 实现检验33品种数据是否是正态分布
2019/12/09 Python
python中导入 train_test_split提示错误的解决
2020/06/19 Python
python下载的库包存放路径
2020/07/27 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
python使用selenium爬虫知乎的方法示例
2020/10/28 Python
python 邮件检测工具mmpi的使用
2021/01/04 Python
纯CSS实现聊天框小尖角、气泡效果
2014/04/04 HTML / CSS
在html5的Canvas上绘制椭圆的几种方法总结
2013/01/07 HTML / CSS
一套PHP的笔试题
2013/05/31 面试题
纪念九一八事变演讲稿:忘记意味着背叛
2014/09/14 职场文书
督导岗位职责范本
2015/04/10 职场文书
62句有关感恩节文案(推荐收藏)
2019/11/28 职场文书
python 破解加密zip文件的密码
2021/04/22 Python
解决MySQL存储时间出现不一致的问题
2021/04/28 MySQL
Python+Appium自动化测试的实战
2021/06/30 Python
使用javascript解析二维码的三种方式
2021/11/11 Javascript