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 相关文章推荐
jquery ajax执行后台方法
Mar 18 Javascript
jquery实现隐藏与显示动画效果/输入框字符动态递减/导航按钮切换
Jul 01 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 Javascript
AngularJS实现ajax请求的方法
Nov 22 Javascript
bootstrap导航栏、下拉菜单、表单的简单应用实例解析
Jan 06 Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
Feb 11 Javascript
详解vue中router-link标签所必备了解的属性
Apr 15 Javascript
关于微信小程序map组件z-index的层级问题分析
Jul 09 Javascript
小程序实现搜索框
Jun 19 Javascript
ES6中Symbol、Set和Map用法详解
Aug 20 Javascript
Vue中jsx不完全应用指南小结
Nov 01 Javascript
vue-cli创建的项目中的gitHooks原理解析
Feb 14 Javascript
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 数组动态添加实现代码(最土团购系统的价格排序)
2011/12/30 PHP
PHP函数rtrim()使用中的怪异现象分析
2017/02/24 PHP
向大师们学习Javascript(视频与PPT)
2009/12/27 Javascript
jquery.cookie.js 操作cookie实现记住密码功能的实现代码
2011/04/27 Javascript
用jquery实现点击栏目背景色改变
2012/12/10 Javascript
JS脚本defer的作用示例介绍
2014/01/02 Javascript
使用jquery实现的一个图片延迟加载插件(含图片延迟加载原理)
2014/06/05 Javascript
JS/Jquery判断对象为空的方法
2015/06/11 Javascript
node.js调用C++开发的模块实例
2015/07/03 Javascript
基于javascript实现图片切换效果
2016/04/17 Javascript
js实现九宫格的随机颜色跳转
2017/02/19 Javascript
使用vue和datatables进行表格的服务器端分页实例代码
2017/06/07 Javascript
vue-router配合ElementUI实现导航的实例
2018/02/11 Javascript
H5+C3+JS实现五子棋游戏(AI篇)
2020/05/28 Javascript
vue动画之点击按钮往上渐渐显示出来的实例
2018/09/29 Javascript
解决vuecli3中img src 的引入问题
2020/08/04 Javascript
前端性能优化建议
2020/09/17 Javascript
Python numpy 点数组去重的实例
2018/04/18 Python
python3+opencv3识别图片中的物体并截取的方法
2018/12/05 Python
python实现三次样条插值
2018/12/17 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
python 最简单的实现适配器设计模式的示例
2020/06/30 Python
canvas绘制表情包的示例代码
2018/07/09 HTML / CSS
html5-canvas中使用clip抠出一个区域的示例代码
2018/05/25 HTML / CSS
详解如何获取localStorage最大存储大小的方法
2020/05/21 HTML / CSS
英国著名的小众美容品牌网站:Alyaka
2017/08/08 全球购物
应届大学生的推荐信
2013/11/20 职场文书
医学生就业推荐表自我鉴定
2014/03/26 职场文书
计算机应用应届生求职信
2014/07/12 职场文书
防灾减灾日活动总结
2014/08/26 职场文书
综治工作心得体会
2014/09/11 职场文书
解除劳动合同证明书模板
2014/11/20 职场文书
特此通知格式
2015/04/27 职场文书
二年级数学教学反思
2016/02/16 职场文书
教你用Java Swing实现自助取款机系统
2021/06/11 Java/Android
MySQL 聚合函数排序
2021/07/16 MySQL