分配给组件属性时,防止将对象转换为反应性对象

时间:2019-07-11 20:38:32

标签: vue.js vuejs2 vue-component

这有点奇怪,抱歉。

我正在使用第三方库从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调用中获取响应,并使用它来生成lib.User类型的实例。至此为止,一切都很好,但是一旦我将响应分配给组件中的一个属性,新的'lib.User'实例就会启动多个函数,并且开始出现很多错误。

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

如果可以避免的话,我希望将此对象包含在组件中,而不必将其映射到本地生成的对象。

反正有这种行为吗?

1 个答案:

答案 0 :(得分:1)

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

方法1

请勿在组件实例上将user定义为反应性数据属性。我不确定如何在Typescript中执行此操作,但是通常您会从数据对象中省略user,而是在this.user钩子中初始化created

其结果是this.user属性将不会起作用。这可能不是您想要的。

方法2

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

this.user = Object.freeze(user)

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

您也许可以改用Object.seal()Object.preventExtensions()

方法3

您可以通过将user对象的_isVue属性分配为true来欺骗Vue认为user._isVue = true this.user = user 对象已经是反应性的;这样Vue就不会观察到它。

{{1}}

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