美文网首页
$set是否是无法刷新视图的万能解决办法?

$set是否是无法刷新视图的万能解决办法?

作者: microkof | 来源:发表于2017-12-05 15:14 被阅读47次

前言

目前我在使用vue开发,今天,我遇到了一个怪事:

data上的数据,从{}到一个多层json,这一步没问题,视图得到了响应,但是,当修改这个多层的json的一个低层的值的时候,注意,并不是新增键,而是只是修改值,结果,死活得不到视图的响应。

见了鬼了?

查了查资料,说是跟“ Vue 无法探测普通的新增属性 ”有关系。然而,我这也不是新增的属性,只是在修改属性,不知道为何同样得不到响应。

教程上说,用this.$set()强制刷新视图即可,那么我就试了试:

我想修改的键是:

      this.notebook[cardKey].filter((v) => {
        return v.id === noteItemId
      })[0].checked

也就是很深的这个checked,按照手册,我写成了这样:

      const thisNoteItem = this.notebook[cardKey].filter((v) => {
        return v.id === noteItemId
      })[0]
      this.$set(thisNoteItem, 'checked', true)

依然不行!

又有资料说,需要用上this.forceUpdate(),经过测试,依然不行!

原因至今没明白,大约是对象的层级实在是太深,加上还用到了过滤函数,导致问题无法解决。

所以这种情况下,不要给自己找麻烦,深层的数据对象,实在无法刷新视图,就不要认死理,而是可以改变一个思路。

解决方法1

因为通常我们都是修改它的一个底层的值,可能是布尔值也可能是其他具体值,下面例子以布尔值为例,那么,另外用一个对象储存你对布尔值的修改,这个对象我称为“diff对象”,它非常简单,只有一层:

diffObj: {
  1: true,
  2: false,
  ...
}

这时候,用this.$set(this.diffObj, noteid, 'checked')就能正确响应了。

解决方法2

也是构建2个对象,一个叫数据对象,一个叫索引对象。比如,你原本的对象是:

[
  {a: [
    {
      id: 1,
      content: 1
    },
    {
      id: 2,
      content: 2
    }
  ]}
]

可以看到,低层对象是:

    {
      id: 1,
      content: 1
    }

其实这个大对象,就是把低层对象分了组,并且给了组名。

那么我们的办法就是:

  1. 低层对象先不要分组,全部平级放在一个数组里,这相当于“数据对象”。
  2. 另外构建一个对象,存放分组,每个分组不再存放低层对象,而是只存放低层对象的索引,这相当于“索引对象”。
  3. v-for循环也是循环两层,是循环“索引对象”,其中深层循环的是索引,当需要取值,就从“数据对象”中取即可。

相关文章

网友评论

      本文标题:$set是否是无法刷新视图的万能解决办法?

      本文链接:https://www.haomeiwen.com/subject/lfrcixtx.html