Why I use vue-class-component

Readable class rather than an odd JS Object

Kengo Hamasaki / hmsk
Hai-iro
4 min readApr 29, 2018

--

Arranging my thoughts for vue-class-component to shorten my explanation 🤕

vue-class-component

vue-class-component provides @Component decorator to write Vue components with JS/TS Class style. There are some reasons I prefer to use this style.

  • Readability
  • TypeScript Friendly
  • To use vuex-class
  • Officially maintained

Readability

Vue component works by giving JS Object which fulfills Vue’s expectation.

export default {
//scoped variables in this component
data () {
return {
message: 'Hello'
}
},
// observed variables (by function)
computed: {
reversedMessage () {
return this.message.split('').reverse().join('')
}
},
// functions firing by template
methods: {
changeMessage () {
this.message = "Good bye"
}
},
// child components this component calls
components: { },
// variables passed from parent template
props: { },

// Lifecycle hooks
created () { },
mounted () { },
updated () { },
destroyed () { }
}

Firstly, there are many members. ‘data’ should be a function which returns an object (If reused in a couple of places, “must be”, if not, “doesn’t matter”). computed has functions which return value for a template. methods has functions which are fired by template or other function. When working on implementation, should thinks about where I should add my code always.

vue-class-component omits and shorten such like this conventions.

@Component({
components: { },
props: { },
})
export default class extends Vue {
// data
message = 'Hello'
// computed
get reverseMessage () {
return this.message.split('').reverse().join('')
}
// method
changeMessage () {
this.message = 'Good bye'
}
// Lifecycle hooks
created () { },
mounted () { },
updated () { },
destroyed () { }
}

That’s so arranged for ease of understanding about what the component does, right? ✨ As like OOP’s class definition, can write naturally.

data is expressed as member variables of a class. The rest is member functions. Additionally, computed should have get accessor. When I see a function, understand whether that is computed or method without looking for parent key. Also glad to see shallow nesting.

What if I need to call a function in method from lifecycle hooks, the hook function just calls other member function. It’s so natural instead callee is in method: { callee () { } } 😉

components and props appear as arguments of @Component decorator unlike class’ implementation. This makes sense for me since these are one-time definitions to configure component.

However, you don’t think so about watch which may have logic like computed functions, and then you may use vue-property-decorator for writing in inside of class’ implementations) 💡 I want to avoid having watch as I possibly can though.

TypeScript Friendly

TypeScript class provides many benefits as typed language: Abstraction, Inheritance and Editor’s powerful support (especially by VSCode).

If the team intend to use TypeScript for the project, vue-class-component may be a natural choice than ES6 or Babel-ized JavaScript.

To use vuex-class

My components have to map functions to use Vuex.

vuex-class provides @Getter, @State, @Action, @Mutation decorators for shortening Vuex methods mapping.

@Component
export default class extends Vue {
@Action foobar
created () {
this.foobar();
}
}

We can map Vuex factors with naturally rather than …mapActions(['dispatch']) 💚

To use this syntax I might choose vue-class-component.

Officially maintained

vue-class-component is owned by vuejs organization on GitHub. Started as vue-classy by Evan who is the creator of Vue.js. Moreover, recently Vue.js has some priorities to support TypeScript as long as I see them.

This means vuejs organization doesn’t drop supporting the class style suddenly. I expect new features, and improvements will be supposing about vue-class-component.

Downsides

Unfortunately, I don’t recommend using vue-class-component for every Vuers. There’re some downsides I was seeing.

  • Not matched to samples
    The official document is entirely not showing any sample for vue-class-component way (even for TypeScript), so we should have the converter in our brain which requires some knowledge about Vue beforehand.
  • Lose benefits which I would have if I take proper way
    Some excellent libraries may not work for your project, and they don’t have any plan to support. By not using Vue straightly, other people forget about us in some cases.
  • New-ish style
    The decorator is still kinda “beta”, so not enough support by editor/linter/prettier…
  • Bundled JS becomes a bit bigger…?
    Decorator codes are bundled for each component by TypeScript’s specification (Decorator runs in runtime to mutate the source code).

When we may stop using vue-class-component

  • Not maintained officially by Vue core team
  • Block using the latest features of Vue significantly

--

--