Skip to content

[Vue v3] Changes for @Component decorator and Vue base class #406

Open
@ktsn

Description

@ktsn

Summary

  • @Component will be renamed to @Options.
  • @Options is optional if you don't declare any options with it.
  • Vue constructor is provided from vue-class-component package.
  • Component.registerHooks will move to Vue.registerHooks

Example:

<template>
  <div>{{ count }}</div>
  <button @click="increment">+1</button>
</template>

<script>
import { Vue, Options } from 'vue-class-component'

// Component definition
@Options({
  // Define component options
  watch: {
    count: value => {
      console.log(value)
    }
  }
})
export default class Counter extends Vue {
  // The behavior in class is the same as the current
  count = 0

  increment() {
    this.count++
  }
}
</script>
// Adding lifecycle hooks
import { Vue } from 'vue-class-component'

Vue.registerHooks([
  'beforeRouteEnter',
  'beforeRouteLeave',
  'beforeRouteUpdate'
])

Details

As Vue v3 no longer provides base Vue constructor, Vue Class Component will provide it instead. Fortunately, we can add class component specific features in the base class as we define it in Vue Class Component package.

One of the benefits with the new Vue constructor is we can make @Component decorator optional. There were non-trivial number of confusions regarding missing @Component decorator in super class / mixins (e.g. #180). Making decorator optional would solve this problem.

Also renaming @Component with @Options would make more sense as it is for adding component options to your class components rather than making a class component.

Since @Options is optional, having registerHooks on the decorator will not work. So we will move the method under static field of Vue constructor.

Alternative approach

Declaring component options as static properties

We could do this to define class component options:

export default class Counter extends Vue {
  // All component options are static properties
  static watch = {
    count: value => {
      console.log(value)
    }
  }

  count = 0

  increment() {
    this.count++
  }
}

But it has a drawback: we cannot define static properties / methods not for component options both on userland and library side. e.g. we cannot define static method like registerHooks on Vue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions