TypeScriptベースでVue.js コンポーネントの書き方の違いを比較

vuejs

TypeScriptを利用した場合と利用しない場合でVue.js コンポーネントの書き方がどのように変わるのかを比較しながら記載しています。

Vue.js のコンポーネントの書き方については、よく利用するVue.jsのオプションとサンプルコードの纏めを参照してください。

Vue.js や Nuxt.js で TypeScriptを利用するためにはvue-property-decorator というデコレータを利用します。(Nuxt.js の場合は、nuxt-property-decorator を利用します。)

  • コンポーネントの定義
  • Data
  • Computed
  • メソッド
  • ライフサイクルフック
  • @Component
  • @Prop
  • @Watch
  • @PropSync
  • @Emit

コンポーネントの定義

通常の書き方

<script>
export default {
  name: 'SampleComponent'
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {}
</script>

Data

通常の書き方

<script>
export default {
  data() {
    return {
      name: 'simochee',
      age: 21
    }
  }
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  name = 'simochee';
  age = 21;
}
</script>

Computed

通常の書き方

<script>
export default {
  data() {
    return {
      score: 55
    }
  },
  computed: {
    triple() {
      return this.score * 3;
    }
  }
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  score = 55;

  get triple() {
    return this.score * 3;
  }
}
</script>

メソッド

通常の書き方

<script>
export deafult {
  methods: {
    onClickButton() {
      // ボタンが押されたときの処理
    }
  }
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  onClickButton() {
    // ボタンが押されたときの処理
  }
}
</script>

ライフサイクルフック

通常の書き方

<script>
export default {
  mounted() {
    // コンポーネントがマウントされたときの処理
  },
  beforeDestroy() {
    // コンポーネントが破棄される直前の処理
  }
}
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  mounted() {
    // コンポーネントがマウントされたときの処理
  }

  beforeDestroy() {
    // コンポーネントが破棄される直前の処理
  }
}
</script>

@Component

通常の書き方

<script>
export deafult {
  components: {
    AppButton,
    ProductList
  },
  directives: {
    resize
  },
  filters: {
    dateFormat
  },
  mixins: [
    PageMixin
  ]
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component({
  components: {
    AppButton,
    ProductList
  },
  directives: {
    resize
  },
  filters: {
    dateFormat
  },
  mixins: [
    PageMixin
  ]
})
export default class SampleComponent extends Vue {
}
</script>

@Prop

通常の書き方

<script>
export deafult {
  props: {
    userName: {
      type: String,
      required: true
    },
    isVisible: {
      type: Boolean,
      default: false
    }
  }
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  @Prop({ type: String, required: true })
  userName: string;

  @Prop({ type: Boolean, defualt: false })
  isVisible: boolean;
}
</script>

@Watch

通常の書き方

<script>
export deafult {
  data() {
    isLoading: false,
    profile: {
      name: 'simochee',
      age: 21
    }
  },
  watch: {
    isLoading() {
      // ローディング状態が切り替わったときの処理
    },
    'profile.age': {
      handler: function() {
        // プロフィールの年齢が変更されたときの処理
      },
      immediate: true
    } 
  }
};
</script>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, Watch, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  isLoading = false;
  profile = {
    name: 'simochee',
    age: 21
  };

  @Watch('isLoading')
  onChangeLoadingStatus() {
    // ローディング状態が切り替わったときの処理
  }

  @Watch('profile.age', { immediate: true })
  onChangeProfileAge() {
    // プロフィールの年齢が変更されたときの処理
  }
}
</script>

@PropSync

通常の書き方

// 親コンポーネント
<template>
  <!-- 以下の2つは同じ意味 -->
  <ChildComponent
   :childValue.sync="value"
  />
  <ChildComponent
    :childValue="value"
    @update:childValue="value = $event"
  />
</template>

TypeScriptを利用した書き方

<script lang="ts">
import { Component, PropSync, Vue } from 'vue-property-decorator';

@Component
export default class SampleComponent extends Vue {
  @PropSync({ type: String })
  childValue: string;

  // value を変更したいときに呼び出す
  updateValue(newValue) {
    this.childValue = newValue
  }
}
</script>

@Emit

通常の書き方

// 子コンポーネント
<template>
  <form @submit="onSubmit">
    <input v-model="value">
    <button type="submit">Submit</button>
  </submit>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class ChildComponent extends Vue {
  value = '';

  // 値を送信する処理
  onSubmit() {
    this.$emit('submit', this.value);
  }
}
</script>

TypeScriptを利用した書き方

<template>
  <form @submit="submit">
    <input v-model="value">
    <button type="submit">Submit</button>
  </submit>
</template>

<script lang="ts">
import { Component, Emit, Vue } from 'vue-property-decorator';

@Component
export default class ChildComponent extends Vue {
  value = '';

  // 値を送信する処理
  // イベント名を指定しない場合でも () は省略できない
  @Emit()
  submit() {
    return this.value;
  }
}
</script>

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。