Nuxt.jsでコンポーネントを作成してコードの共通化を行う|Nuxt.jsの基本

Nuxt.jsでもコンポーネントが作成できて、作り方はVue CLIとほとんど同じになります。
今回はNuxt.jsのコンポーネントの基本的な部分をまとめておきます。
コンポーネントファイルの作成
コンポーネントファイルは「/components」フォルダ内に作成します。
今回は例として、ボタン用のコンポーネントの「/components/PrimaryButton.vue」を作成します(コンポーネントの名前はパスカルケースで書きます)。
PrimaryButton.vue内には<template>内にHTML、<style>内にCSS、<script>内にJavaScript(Vue.js)を書いて、ボタンに関するすべてがファイル1つにまとまっている状態になります。
このように1つのコンポーネントに対するHTML・CSS・JavaScriptを1ファイルにまとめることを「単一ファイルコンポーネント」と呼びます。
<template>
<!-- HTMLを記述 -->
</template>
<style scoped>
/* CSSを記述 */
</style>
<script>
export default {
//JavaScript(Vue.js)を記述
}
</script>template内の記述
コンポーネントのHTML要素を記述していきます。
ルールとして、必ず<template>直下はHTMLタグが1つとなる必要があります。
下記は<template>直下に<button>と<p>が2つあるので、この場合はエラーになってしまいます。
<template>
<button @click="onClickButton">{{buttonText}}</button>
<p>{{smallText}}</p>
</temaplte>下記のように、<div>で囲って<template>直下がHTMLタグ1つになればOKです。
<template>
<div>
<button @click="onClickButton">{{buttonText}}</button>
<p>{{smallText}}</p>
</div>
</temaplte>style内の記述
CSSの記述をしますが、<style scoped>とすることで、その中で指定したCSSはこのコンポーネントにのみ適用されるようにできます。
通常のウェブサイトではCSSが他の場所に影響しないようにclass名を工夫したり、被らないように親要素にclassを用意して…などしますが、その必要はなくなります。
class名もシンプルなものが使えたり、タグ名をそのまま指定することも許されます。
逆にscopedがないと、サイト全体に影響が出るので注意が必要です。
scriptの記述
Vue.jsの記述をしますが、通常のVue.jsと変わりません。
dataは関数として定義する必要があるので、そこだけ注意しましょう。
<script>
export default {
data: () => ({
}),
metdhos: {
onClickButton() {
console.log('click')
},
}
}
</script>コンポーネントファイルの読み込み
コンポーネントファイルはimportでインポートするのと、export default内のcomponents:{}で指定します。
あとは<template>内でケバブケースに変換した状態でHTMLタグとして記述します。
<template>
<primary-button></primary-button>
</template>
<script>
import PrimaryButton from '~/components/PrimaryButton'
export default {
components: {
PrimaryButton,
},
}
</script>さらに高度なscriptの設定
プロパティの設定
コンポーネントではオプションオブジェクトにプロパティ(props)を渡して、それを使って処理を書きます。
script内にキャメルケースでprops内にプロパティ名と、その定義をします(必須ではないですが、予期せぬエラーを防げます)。
| 定義 | 内容 | 備考 |
|---|---|---|
| type | プロパティのデータ型 | String(文字列) / Number(数字) / Boolean(真偽値) / Array(配列) / Object(オブジェクト) |
| default | プロパティの指定がなかった場合のデフォルト値 | |
| required | プロパティの指定が必須かどうか | trueかfalseを指定 |
| validation | プロパティのバリデーション関数 |
<script>
export default {
props: {
backgroundColor: {
type: String,
default: '#00f'
}
}
}
</script>script内のmethodsなどの他の場所で使用するときは「this.buttonText」のようにして扱います。
template内で使用するときは名前そのまま波括弧2つで「{{buttonText}}」のようにするとテキストとして出力されます。
属性内で使用したい場合は、属性名の最初に「:(コロン)」が付いている状態で名前そのまま「:href="link"」のようにして入力します(「href="link"」だと「link」という文字列そのまま出力されてしまうため、プロパティから引っ張ってこられない)。
データで動的に変わる属性は「:(コロン)が付く」と覚えておきましょう。
コンポーネント読み込み時にpropsにデータを渡す
コンポーネント読み込み時にprops名をキャメルケースからケバブケースにして属性名として設定します。
<template>
<primary-button background-color="#f00"></primary-button>
</template>これも変数などを渡す場合は場合は「:background-color」のように先頭に「:(コロン)」を付けます。
$emit
$emitを使うと、親ページにデータを渡したり、イベントが発火したことを親ページに知らせられます。
例えばボタンコンポーネント内のボタンをクリックしたときに、クリックされたことを親ページに知らせて、そこから先の処理は親ページで行えます。
methods: {
onClickButton() {
this.$emit('button-click')
}
}親ページでは$emitの第一引数の名前の先頭に「@」を付けて、関数名を指定します(この関数はもちろん親ページ内の関数です)。
<primary-button @button-click="onChangePage"></primary-button>図にすると下記のような流れになります。
slot
ボタンに表示するテキストなど、コンポーネント内のHTMLをそのまま親要素から指定できます。
また、<slot>内に入力した要素にはデフォルトの表示を設定できます(空でも問題ありません)。
<template>
<button @click="onClickButton">
<slot>何も入力されていない場合のデフォルト表示</slot>
</button>
</template>コンポーネント読み込み時にコンポーネントタグで囲った要素が、<slot>内に表示されます。
<template>
<primary-button">ボタンテキスト</primary-button>
</template>



Movable TypeでAssetURLやEntryPermalink・ContentPermalinkで出力されるパスを絶対パスから相対パスに変える
CSSの読み込みで「its MIME type (‘text/html’) is not a supported stylesheet MIME type」エラーが表示されて読み込みができない場合の解決方法
webpackでTop-Level Awaitを使用して、一番上位でもawaitを使えるようにする方法
JetpackでのError during WebSocket handshakeの解決方法
ダミーとして使うURLは適当に入力せず、決まったものを使うようにしよう
Visual Studio Codeで正規表現にマッチするか確認できる拡張機能「Regex Previewer」
常時SSL化の設定をしたのに「保護された通信」が表示されない時はパスにHTTPが残っているのかも?
CSSのカスタムプロパティ(変数機能)の使い方
Visual Studio Codeで連番を入力する拡張機能「vscode-input-sequence」
スマホやPCにプッシュ通知をしてくれる「Push7」をブログに追加する方法
MacのKeynoteにハイライトされた状態でコードを貼り付ける方法
AirPodsで片耳を外しても再生が止まらないようにする方法
iTerm2でマウスやトラックパッドの操作を設定できる環境設定の「Pointer」タブ
DeepLで「インターネット接続に問題があります」と表示されて翻訳できないときに確認すること
Ulyssesの「第2のエディタ」表示を使って2つのシートを横並びに表示する
macOSの効率化に関するDiscordコミュニティ「CMD-F」を立ち上げました
1Passwordの開発者向け機能(SSH Agent / Environments / 1Password CLI / Developer Watchtower)
Default Folder Xで保存ダイアログ内のファイルリストにフォーカスする方法
Obsidianで整理した知識をAnkiで定着させる方法
Figma × Keyboard Maestroでどこまで効率化できる?
マウス操作の完成度が高いウインドウリサイズアプリ「Magnet」
Macで複数ディスプレイを使っている場合に便利な設定集
AppCleanerでMacアプリを関連ファイルごと完全に削除する
操作に没頭できる!Firefox版 Arcのようなブラウザ「Zen Browser」
chezmoi(シェモア)で始めるdotfiles管理