# 类组件的注意事项

Vue 类组件通过在幕后实例化原始构造函数来收集类属性作为 Vue 实例数据。虽然我们可以像原生类方式一样定义实例数据,但有时我们需要了解它的工作原理。

# 属性初始化器中的 this

如果您将箭头函数定义为类属性并在其中访问 this,它将不起作用。这是因为 this 在初始化类属性时只是一个代理对象,指向 Vue 实例。

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class MyComp extends Vue {
  foo = 123

  // DO NOT do this
  bar = () => {
    // Does not update the expected property.
    // `this` value is not a Vue instance in fact.
    this.foo = 456
  }
}

在这种情况下,您可以简单地定义一个方法而不是类属性,因为 Vue 会自动绑定实例。

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class MyComp extends Vue {
  foo = 123

  // DO this
  bar() {
    // Correctly update the expected property.
    this.foo = 456
  }
}

# 始终使用生命周期钩子而不是 constructor

由于原始构造函数被调用以收集初始组件数据,因此建议不要自己声明 constructor

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Posts extends Vue {
  posts = []

  // DO NOT do this
  constructor() {
    fetch('/posts.json')
      .then(res => res.json())
      .then(posts => {
        this.posts = posts
      })
  }
}

上面的代码意图在组件初始化时获取帖子列表,但由于 Vue 类组件的工作方式,fetch 会意外地被调用两次。

建议使用 created 等生命周期钩子而不是 constructor

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Posts extends Vue {
  posts = []

  // DO this
  created() {
    fetch('/posts.json')
      .then(res => res.json())
      .then(posts => {
        this.posts = posts
      })
  }
}