shigeki.takeguchi.log

アラフィフおじさんの技術日記

Nuxt.js + TypeScript(Class-based)にはnuxt-property-decorator

Nuxtにはvue-property-decoratorじゃなくてnuxt-property-decoratorってのがある

ちょっとブログをNuxt + contentfulでの構築を試しているときに最初は vue-property-decorator を使ってましたがどこかの記事で nuxt-property-decorator があることを知って最終的にはそっちを使ってます。
TypeScriptでクラスベースでVue(Nuxtも含む)を記述しようとすると vue-property-decorator を基本的には使ったほうがよいと思います。

vue-class-component を使っても良いですがどちらかというと vue-property-decorator の情報の方が今は多い印象です。

この記事ではわかりやすく vue-class-componentvue-property-decorator の違いを整理してくれています。
TypeScriptでクラススタイルコンポーネントを実装する方法

構築した環境では実際のところ、とくに vue-property-decorator でもエラーや不具合が出ませんでした。

Nuxtにはトップレベルのコンポーネント単位で head タグ内での要素を記述したり上書きしたりする機能があるのですが、ネットで散見される記事ではその機能が vue-property-decorator ではうまく動かないという情報もありましたので念のために nuxt-property-decorator を使ったほうが良さそうです。

1
2
3
4
5
head(){
return {
title: 'ページやサイトのタイトル'
}
}

vue-property-decoratorをnuxt-property-decoratorに入れ替える

vue-property-decorator を削除しましょう。

1
yarn remove vue-property-decorator

npmの場合

1
npm uninstall --save vue-property-decorator

nuxt-property-decorator を追加します。

1
yarn add nuxt-property-decorator

npmの場合

1
npm install --save nuxt-property-decorator

nuxt.config.jsを編集する

nuxt.config.jsに追記しましょう。

1
2
3
4
5
6
7
8
build: {
babel: {
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-class-properties", { loose: true }]
]
}
}

【サンプルソース】contentfulからblogのポストを取得する記述です。

Nuxtでは asyncData というコンポーネントのデータをセットする前に非同期の処理が実行できる便利なメソッドがあります。

API: asyncData メソッド - NuxtJS

でこの asyncData ですがどこに記述するのかというと @Component デコレータに記述しておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script lang="ts">
import { Vue, Component } from 'nuxt-property-decorator'
import client from '~/plugins/contentful.js'

@Component({
components: {
Card: () => import('~/components/Card.vue')
},
async asyncData ({ env, params }) {
return await client.getEntries({
'content_type': 'blogPost',
'fields.slug': params.slug,
}).then(entries => {
return {
post: entries.items[0],
}
})
.catch(console.error)
},
head(this): object {
return {
titleTemplate: null,
title: this.post.fields.title,
}
}
})

export default class Slug extends Vue {
mounted() {}
}
</script>

head メソッドも @Component デコレータに記述できるのですがcontentfulから取得したデータは head の引数に this が渡されてくるのでそれを利用します。 asyncData 内の以下の記述での postprops 扱いになるため this から参照できます。

1
2
3
return {
post: entries.items[0],
}

Nuxtはこれに代表されるような便利な機能がけっこうあります。

shigeki.takeguchi

渋谷の某ソーシャルゲームの会社でフロントエンドエンジニアとして働いてます。20世紀よりウェブ業界。気づいたらアラフィフ業界人です。
まだまだ現場で粘り強く作る側でいたいと思います。