小白使用 vue2.6.10 的 v-for 遇到的一个问题从而引发了一个对于这一行业的思考,希望有人可以开导我

2019-08-08 21:07:20 +08:00
 zazalu
我遇到的问题是这样的,我描述下:

问题 1:

父组件使用"props"传递一个数组"items"给子组件,

子组件使用 v-for 处理这个"items"来循环打印"item"中的 content 字段内容,

过了一段时间后,我会去触发一次父组件的 items 更新,类似如下代码:

```
this.items = this.items.concat([{id:11, content: "第十一条通知"}])
```

因为 vue 官方文档说过,如果是非变异方法改变数组内容,直接使用"replace a array"的方式,也就是我上面的方式.

所以我认为我的代码是没问题的.

但是事实却痛击了我, 不知道为啥 v-for 循环并没有刷新数据.

于是我先使用{{items}}检查了 props 的数据是否已经更新.

结果是{{items}}确实已经更新了第十一条通知的内容进去.

并且我使用 slice 方法去更新数组内容,是可以的, 就唯独 concat 方法不行

问题 2:

问题 2 是我在问题 1 后出现的一个新问题.

我将{{items}}放到了 v-for 所在组件的后面(问题 1 中我是放在最前面验证的), 这时候神奇的事情发生了.

v-for 居然更新了内容.

所以 vue 内部到底发生了什么... 我该怎么去解... 文档我也上下翻了好几次, google,baidu 了类似问题,但是很遗憾没有和我遇到一样问题的伙伴出现

问题 3:

我依旧不服, 想着在单元测试中也试试会不会存在这个问题,

所以我使用 vue-cli 创建了一个超级简单的 vue 单组件项目作为我的单元测试项目, 然后我将一些核心代码移了过去,重新测试了下

(我强调下, 单元测试的代码肯定是和我真正项目中用的是一样的! )

结果是没有任何问题, v-for 工作完全正常!

我.................................................................................



总结:

到最后, 我没法搞定这个问题(我采用的是问题 2 中描述的折中但是非常不优雅的写法), 感觉内心非常的难受, 关电脑, 回宿舍, 简单的吃了下晚饭, 吃着吃着差点掉眼泪 , 感觉写代码也至少一年多了, 这类问题以前在使用 jsp 的时候其实也遇到过类似的. 结果,一年过去了, 我连这种问题都没法搞定, 还谈什么设计模式,算法呢, 一年来感觉压根没有多大提升, 除了找资料和看英文文档能力感觉比以前强了以外, 能做的无非只有 crud.

这么一个问题, 搞得我焦头烂额,浪费了一下午+晚上几个小时的青春. 我想真诚的问下各位前辈们, 是不是我这种人不适合做程序员
8974 次点击
所在节点    Vue.js
121 条回复
jydeng
2019-08-08 21:17:46 +08:00
上代码看看,想那么多没啥意思
mosade
2019-08-08 21:25:53 +08:00
试试```
this.items.push(...array);
```
FakeLeung
2019-08-08 21:27:16 +08:00
事实是,我用 this.data = [] this.data = res 这种方法是可以触发更新的。
shintendo
2019-08-08 21:39:14 +08:00
没代码不好猜,直觉告诉我跟 key 有关系
shintendo
2019-08-08 21:41:09 +08:00
其实问题只要能稳定复现,排查就是一件很有意思的事,反正我是这么觉得
gouflv
2019-08-08 23:36:07 +08:00
vue 是开源的,后面要做什么你懂了吧?
xalilo
2019-08-08 23:45:42 +08:00
明天我试试
SuperMild
2019-08-09 00:02:59 +08:00
这个你不先要怪自己,有可能是某个小地方不小心写错了,有时候一个意想不到的地方的小问题是很难发现。
mamahaha
2019-08-09 00:48:16 +08:00
你的父组件传到子组件还用原来的变量名吗?那你这个变量属于父组件还是子组件?
airyland
2019-08-09 03:00:46 +08:00
@gouflv 阴阳怪气,不知所云。
zazalu
2019-08-09 03:01:34 +08:00
问题解决了,虽然我不知道为啥(写程序以来, 第一次彻底放弃思考了 ,以前的问题我一般都会刨根问底的)

我就改了一个地方,就一切正常了.不会出现唯独 concat 方法不会触发 v-for 更新的问题, 如下

在我主题中说的子组件中其实还套用了另一个组件,叫 new-message, 我在其外围包裹了一个 div 后, v-for 的功能突然就一切正常了, 不会变得稀奇古怪的.

```
<template>
<div>

<p v-for="item in messageItems" :key="item.id">{{item.content}}</p>

<div> <!-- 在此添加一个 div 来包裹 new-message 这个组件, 一切就都正常了 -->
<new-message ref="newMessage" @on-success-valid="handleNewMessage"></new-message>
</div>

</div>
</template>

<script>
export default {

props: {
messageItems: {
type: Array
}
},

//.....

}

</script>

```

---------------

顺便回复下楼上一些好心大佬的回答:

1. 我使用 push 也不会触发更新
2. 我检查了 key 是否重复,随后我故意重复发现 vue 会报错,也证明了我数据应该没有问题
3. 用 this.data = [] this.data = res 这种语法赋值会触发更新, 我已经说了,是唯独 concat 函数去更新不会触发 v-for 的更新

--------------

总结:

第一次对 vue 产生了心理阴影, 也怪我不想看源码(实际上是太菜看的慢,一知半解=不懂, 所以只能不停的测试测试测试)

睡了, 让我自闭会
zazalu
2019-08-09 03:02:53 +08:00
@shintendo 是的, 我认同.
jorneyr
2019-08-09 06:49:27 +08:00
Vue 有的时候确实会出一些逻辑没错,但是就是有问题,我也遇到过,异步请求的复杂对象的数组中的数组显示不出来 (data 中已经预先定义了同样结构的数据显示到界面上),如果是同步请求就没问题、点击按钮创建同样的数据也能正常显示 (逻辑上和异步请求是一样的嘛),但就是异步请求得到的对象显示不出来,不管了,直接同步请求吧。
qyb
2019-08-09 07:05:29 +08:00
我觉得楼主已经很有条理了,应该没问题的
jatai
2019-08-09 07:16:30 +08:00
没用过 vue,但是看文档,好像都是建议用 setState 来更新数据的。不知道对不对
Biwood
2019-08-09 07:59:23 +08:00
你的 new-message 组件的 ref 值在遍历的时候重复了,要知道 ref 在当前组件里面必须是唯一的,是否因为这个导致了其他错误?
iamdhj
2019-08-09 08:41:58 +08:00
没代码不好确定问题,建议遇到问题可以把逻辑逐步精简,那样更容易找到问题根源
libook
2019-08-09 08:50:51 +08:00
楼主的目的在于抱怨,但其他 V 友在尝试帮楼主解决问题。

所以楼主干脆把完整代码发上来?可以存到 Github 上面然后发个链接出来。

我自己带实习生的时候,总是要求他们遇到问题先尝试自己解决,但如果两个小时仍然没有实质进展的话,再继续抠下去也没有多大帮助,这时候就需要提问,问身边的人或者去 StackOverflow 等社区提问,你英语好的话用英文提问应该没压力吧?实在罕见的问题去框架官方 GIthub 上提 issue。如果用的东西实在冷门,连官方都无暇回复,也可以自己研究源代码。

上面这段实际上就是程序员的日常,没有人生来就能解决所有问题,但不应该拒绝学习。
asdjgfr
2019-08-09 09:03:16 +08:00
codepen 上代码啊,大部分人为自己没问题的时候其实都是有问题的,特别 js 这种灵活的语言
1KN6sAqR0a57no6s
2019-08-09 09:06:29 +08:00
前端领域是热闹又孤独的。当你对 1+1 有疑惑的时候,所有人都能说上两句; 当你被 0.1 + 0.2 困住的时候,只能靠你自己。答非所问是搜索引擎的常态,也是人的常态。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/590284

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX