Make it to make it

いろいろ作ってアウトプットするブログ

vue-class-componentの導入

一般的なVueコンポーネントの書き方は、オブジェクト志向でclassコンポーネントに慣れている人にとっては特殊な書き方である面が大きいだろう。

vue-class-componentを導入すれば、classスタイルなVueコンポーネントが書ける。

vue-class-componentの特徴

  • methodはclassのメンバメソッドとしてダイレクトに書ける
  • computedプロパティはclassプロパティアクセサーとして書ける
  • 初期のdataはclassプロパティとして宣言できる
  • data, renderやその他のVueライフサイクルフックもclassのメンバメソッドして宣言できるが、Vueインスタンス自体にはできない。カスタムメソッドを作成する際には、当然ながら予約語は避けるべきである
  • その他のオプションに関しては、decoratorファンクションに与える

vue-class-componentの導入手順

必要なパッケージ

  • @babel/plugin-proposal-class-properties
  • @babel/plugin-proposal-decorators

必要な設定ファイル

babel.config.js

  plugins: [
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }]
  ]

jsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

.eslintrc.js

parserOptionsに設定追加

  parserOptions: {
    ecmaFeatures: {
      legacyDecorators: true
    }
  },

今までとの書き方の対比

object (一般的な書き方)

<template>
  <div id="app">
    <button type="button" @click="onClick">Click!</button>
    {{ message }}
  </div>
</template>

<script>
export default {
  data () {
    return {
      message: 'Hello from function'
    }
  },
  methods: {
    onClick () {
      this.message = 'Goodbye'
    }
  }
}
</script>
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App)
}).$mount('#app')

class-style (classの書き方)

<template>
  <div id="app">
    <button type="button" @click="onClick">Click!</button>
    {{ message }}
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({})

export default class App extends Vue {
  message = 'Hello from class'

  onClick () {
    this.message = 'Goodbye'
  }
}
</script>
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => <App />
}).$mount('#app')

propsの記述方法

記述方法1

<template>
  <div id="app">
    {{ message }}
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  props: {
    message: {
      default: 'Hello from default prop'
    }
  }
})

export default class App extends Vue {}
</script>

記述方法2

vue-property-decoratorが必要で、Componentも使える

<template>
  <div id="app">
    {{ message }}
  </div>
</template>

<script>
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'

@Component({})

export default class App extends Vue {
  @Prop({ default: 'Hello from Prop decorator' }) message
}
</script>