首页 > 解决方案 > 防止对象在分配给组件属性时被转换为反应性对象

问题描述

这个有点奇怪,见谅。

我正在使用第三方库从 API 获取一些数据

import lib from 'third-party'
import Vue from 'vue'

@Component({})
export default UserComponent extends Vue{
  public user = null as lib.User | null

  mounted(){
    lib.getUser().then((val: lib.User) => {
      this.user = val; /// this is where things blow up
    })
  }
} // this is from memory, but it looks like a decent recreation ¯\_(ツ)_/¯

因此,lib 采用 API 调用的响应并使用它来生成 type 的实例lib.User。到目前为止一切都很好,但是一旦我将响应分配给组件中的属性,新的“lib.User”实例中的几个函数就会触发,并且我开始收到大量错误。

我的猜测是 Vue 正在将对象属性转换为反应属性,这会导致事件触发。

如果可以避免的话,我希望在组件中有这个对象,而不必将它映射到本地生成的对象。

有没有办法阻止这种行为?

标签: vue.jsvuejs2vue-component

解决方案


假设您的问题的原因是由于对象被响应,那么您可以通过 3 种方式避免这种情况发生。

方式一

不要user在组件实例上定义为响应式数据属性。我不确定如何在 Typescript 中执行此操作,但通常您会user从数据对象中省略,而是this.usercreated挂钩中进行初始化。

这样做的结果是该this.user属性不会是反应性的。这可能不是你想要的。

方式二

如果您将冻结的对象分配给,this.user则 Vue 不会使对象反应:

this.user = Object.freeze(user)

这样做的结果是对象上的所有属性user都将变为只读,这可能不是您想要的。

您可以使用Object.seal()orObject.preventExtensions()代替。

方式3

您可以通过将其上的属性分配给 true来欺骗 Vue 认为该user对象已经是响应式的;_isVue这样 Vue 就不会观察到它。

user._isVue = true
this.user = user

这样做的结果是它不是一个公共 API(据我所知),因此它可能会在未来发生变化(我认为它可能会出现在 Vue 3 中)。


推荐阅读