【译】Vue.set实际上是什么?

网友投稿 228 2022-11-29

【译】Vue.set实际上是什么?

谈到​​Vue.set​​就要说响应式原理,所以得为你自己准备下这方面的理论知识。然而,一如即往,这并不难或者枯燥。准备点鳄梨和薯条,制作些鳄梨酱,然后我们再进入话题。

数据和响应式原理

在一个​​Vue​​​组件中,无论你何时创建一个​​data()​​​功能属性,都会返回一个对象。​​Vue​​在组件背后做了很多事情,来使得它具有响应式。

export default { data() { return { red: 'hot', chili: 'peppers'

​​Vue​​​要做的第一件事是使用我们超帅的​​RHCP(Red Hot Chili Peppers, 一个超赞的乐队)data​​​,它遍历了​​return {}​​​对象的属性​​properties​​​,然后为它们创建了唯一的​​getter​​​和​​setter​​​。具体情况已经超出了本文的范围,但是​​Vue Mastery​​有个很赞的视频去解析这点。

创建这些属性的目的是使你在代码中访问这些属性时(例如通过执行​​this.red​​​或使用​​this.red=hotter​​​进行设置时),实际上是在调用​​Vue​​​为你创建的​​getter​​​和​​setter​​。

在​​SETGET​​​这块神奇的土地上,​​Vue​​​连接起了​​computer properties, watchers, props,data​​​等,从而变得​​响应式​​​。以非常简单的方式,它被称为一个函数,该函数在每次​​setter​​改变时更新整个工作。

陷阱

酷极了!这就是我们喜欢​​Vue​​的原因,它具有响应式和强大的幕后功能。但是也有一些阴暗面需要我们探讨。

在我们开始之前,我们更改下​​data​​数据看发生什么。

data() { return { members: {} }}

好吧,到目前为止没什么看头,我们在​​data​​​中有一个​​member​​​属性,用来添加乐队成员的信息。现在,为了举例,我们添加一个方法,并假装从远程​​{ return { members: {} }},methods: { getMembers() { const newMember = { name: 'Flea', instrument: 'Bass', baeLevel: 'A++' }; // Some magical method that gives us data got us this sweet info // ...

嗯。好吧,我们先停停然后思考下这个例子。如何将​​newMember​​​对象添加到当前的​​member​​属性中?这有许多方法可以解决当前的难题。

也许你会想,我们可以将​​member​​​转换成一个数组,然后将它​​push​​进去。这可行,但是这是在作弊,因为它破坏了我开始输入时细心构造的例子。

在这种情况下,我们​​member​​​是一个​​object​​​。好吧,简单,你会说,我们在​​member​​​上添加一新的属性,这样它还是一个​​object​​​。实际上,我们在​​member​​​上添加个​​name​​属性。

getMembers() { const newMember = { name: 'Flea', instrument: 'Bass', baeLevel: 'A++' // Totally important property that we will never use }; // Some magical method that gives us data got us this sweet info this.members[newMember.name] = newMember; }

Lok'tar Ogar!(不胜则亡)

可是,不,因为-

A. 这不是​​Orgrimmar​​(魔兽世界人物)

B. 现在我们遇到问题了

如果你在浏览器上测试这段代码,你将看到你确实将新数据推入​​member​​数据中了,但是此次的更改组件的状态将不会使得你的应用重新渲染。

仅将这些数据用于某些计算或某种内部存储的情况下,以这种方式进行操作不会影响你的应用程序。然而,这里应该是大大的转折​​HOWERVER​​​,如果你在自己​​app​​​上正在使用这种数据去展示数据,或者根据条件​​v-if​​​或​​v-else​​来渲染,事情将变得有趣。

实际使用Vue.set

所以,现在我们明白问题实际出在哪里了,我们可以学习什么是正确的解决方案。允许我向你介绍​​Vue.set​​。

​​Vue.set​​是一个工具,它允许我们向已经激活的对象添加新属性,然后确保这个新的属性也是响应的。

这完全解决了我们在另一个例子中遇到的问题,因为当我们设置​​member​​​的新属性时,它将自动挂接到​​Vue​​​的响应式系统中,酷酷的​​getters/setters​​​和​​Vue​​的魔法都在框架背后运行。

但是,需要一点说明来了解它如何影响数组。到目前为止,我们只是试验过了​​objects​​​,这很容易理解。新的属性?如果你希望它是响应式,则通过​​Vue.set​​添加。简单~

延续上面的示例,我们切换为使用​​Vue.set​​的方式。

getMembers() { const newMember = { name: 'Flea', instrument: 'Bass', baeLevel: 'A++' }; // Some magical method that gives us data got us this sweet info //this.members[newMember.name] = newMember; this.$set(this.members, newMember.name, newMember); }

这是新添加的​​this.$set(this.members, newMember.name, newMember);​​。

对于这段代码,我有两点想提下。目前为止,我告诉了你​​Vue.set​​​是怎样工作的,但是现在我使用​​this.$set​​​,但是不要担心,这只是个别名,所以它会以完全相同的方式运行。比较酷的是你不用在你的组件中引入​​Vue​​。

我想说的第二点是这个函数的语法。它需要传入三个参数,第一个参数是我们要改变的​​object​​​或​​array​​​(案例上是​​this.members​​)。

第二个参数是指向我们传入第一个参数​​object/array​​​的​​property​​​或​​key​​​(这里是​​newMember.name​​,因为我们想动态生成)。

最后是第三个参数,它是我们想要设置的值(在案例中,​​newMember​​)。

this.members [newMember.name] = newMember;// V V Vthis.$set(this.members, newMember.name, newMember);

(PS. My ASCII skills are not for sale )

但是数组的响应如何?

当我们在最初的状态中创建一个​​array​​​,​​Vue​​​将它设置为响应式,然而,当你直接通过索引赋值,当前​​Vue​​不能检测到。例如,我们如下操作:

this.membersArray[3] = myNewValue;

然而,​​Vue​​​不能检测到这种更改,因此它不是响应式的。请铭记于心,如果你通过​​pop​​​,​​splice​​​,​​push​​操作来更改数组,那么这些操作将触发数组的响应式,所以你可以安全地使用它们。

在必要的时候我们需要直接通过索引赋值,我们可以使用​​Vue.set​​。我们看下它和之前的例子有什么区别。

this.$set(this.membersArray, 3, myNewValue)

如果你想了解更多响应式原理的注意点,请移步[​​link to the official documentation​​​](​​vuejs.org/v2/guide/li…​​)。

Vue 3.0

在编写这篇文章时,这一切仍然可能更改,但是现在满大街都在说这些警告将不再是问题。换言之,​​Vue 3.0​​会让你完全忘记这些边缘的案例,除了那些可怜的人儿,他们必须要针对某些不能完全支持新响应式系统的旧浏览器。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【译】HTTP错误码403禁止:意味着什么,怎么修复它
下一篇:MyBatis自定义SQL拦截器示例详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~