uniapp数据更新视图不更新的问题

14 篇文章 1 订阅
13 篇文章 1 订阅

响应式原理

当我们在 Vue.js 中修改响应式对象的属性时,Vue.js 会自动对修改进行追踪,并在必要时自动更新视图,这是 Vue.js 的响应式系统的核心特性。

Vue.js 的响应式系统是通过数据劫持实现的。在 Vue.js 内部,每个组件实例包含一个拦截器——observe,它可以对组件中的所有数据进行监听。当我们对组件中的数据进行修改时,observe 就会被触发,进而更新对应的视图。这种数据劫持的机制,是依靠 Object.defineProperty 这个 API 实现的。Object.defineProperty 方法可以劫持一个对象,并在对象的 getter 和 setter 被访问时,拦截它们的访问以实现数据劫持。

对于修改对象属性或数组元素,Vue.js 会通过 Vue.set()Vue.delete() 方法来实现响应式更新。当我们通过直接修改数组索引的方式更新数组时,例如:this.list[1] = {name: '小美', age: 18}。这种方式虽然也能生效,但 Vue.js 无法检测到该变更。因为 Vue.js 的追踪机制是在对象初始化时,将对象的数据转换成 getter 和 setter 的形式,并对它们进行监听。因此,如果我们没有使用 Vue.set()Vue.delete() 方法实现更新,Vue.js 就无法发现变化。

使用 Vue.set()Vue.delete() 方法会通知 Vue.js 进行更新视图。这两个方法内部都是通过调用响应式对象的 __ob__ 观测者(Observer)的 dep 通知依赖这个属性的所有 watcher 更新视图。

使用 Vue.set() 方法修改数组或对象属性时会给要修改的对象的属性值,包括新增的属性,上下文对象添加一个响应式标记。同时,当我们向一个对象上添加一个不存在的新属性时,会在该对象上使用 Vue.set() 方法来触发响应式更新。在执行 Vue.set() 方法时,它会根据传入的数据源、具体数据及要赋的值,将其中符合条件的数据添加上响应式标记。当数据源中的已有属性值发生变化时,这个响应式标记会被触发,通知绑定了这个数据的组件更新对应的视图。

强制更新

在 Vue 中,当我们需要强制更新组件时,99.9% 的情况都是因为在某个地方出现了问题。可能是因为我们没有注意到响应式对象的变更检测注意事项,或者依赖了一个未被 Vue 的响应式系统追踪的状态。

如果我们已经注意到了上述的问题并修复了,但仍然需要手动强制更新时,我们可以使用 $forceUpdate() 方法。代码如下:

this.$forceUpdate()

更新响应式对象

Vue.set() 方法可以向响应式对象中添加一个新的 property,并确保这个新 property 同样是响应式的,且能触发视图更新。Vue.set() 方法必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property(比如 this.myObject.newProperty = ‘hi’)。

调用 Vue.set() 方法的语法为:this.$set(target, key, value)。其中:

  • target:要更改的数据源,可以是对象或数组。
  • key:要更改的具体数据。
  • value:重新赋的值。

以下是几种使用 Vue.set() 方法的示例:

data() {
  return {
    list: [
      {
        name: '小明',
        age: 18
      },
      {
        name: '小美',
        age: 12
      }
    ],
    text: '我是未修改的字符串值'
  }
}

// 修改列表中小美的所有数据
this.$set(this.list, 1, {
  name: '小美',
  age: 18
})

// 修改列表中小美的年龄为18岁
this.$set(this.list[1], 'age', 18)

// 修改某个字符串属性
this.$set(this, 'text', '我是修改后的字符串值')

通过以上例子我们可以看到,Vue.set() 方法在修改响应式对象时非常实用。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土拨鼠的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值