Featured image of post Nuxt.jsのvueファイルでJS/CSS/テンプレートを外部ファイル化

Nuxt.jsのvueファイルでJS/CSS/テンプレートを外部ファイル化

Nuxt.jsのvueファイルからHTML(Pug)・JavaScript(TypeScript)・CSS(Sass)をそれぞれ外部ファイル化して、src属性で読み込む方法。言語単位でファイルを分けると修正範囲や影響範囲を絞れて保守しやすくなります♪

1113文字

ファイルを細分化しよう

皆さんはNuxt.jsを使って開発をしていますか?

Nuxt.jsを使ってWebアプリケーションを開発していると、デフォルトでは一つのvueファイルの中に様々な記述をすることになると思います。

基本的には、コンポーネントやページ単位で例として以下のような記述でテンプレートが作成されます。

pages/index.vue
<template lang="pug" >
  section.container
  div
    app-logo
    h1.title.scoped--sample
      | Demo
    h2.subtitle
      | Demo Project
    .links
      a.button--green(href='https://nuxtjs.org/', target='_blank') Documentation
      a.button--grey(href='https://github.com/nuxt/nuxt.js', target='_blank') GitHub
</template>

<script>
import AppLogo from '~/components/AppLogo.vue'

export default {
  components: {
    AppLogo
  }
}
</script>

<style>
.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

.title {
  font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: #35495e;
  letter-spacing: 1px;
}

.subtitle {
  font-weight: 300;
  font-size: 42px;
  color: #526488;
  word-spacing: 5px;
  padding-bottom: 15px;
}

.links {
  padding-top: 15px;
}
</style>

よく見ると、<template>タグのHTML部分<script>タグのJavaScript部分<style>タグのCSS部分3構成になっていますね。

もちろん、このまま手を加えていっても良いのですが、DDD(ドメイン駆動設計)脳としては、コンテキスト単位でファイルを分けたくなってしまいます。。。orz
今回で言うと、HTML/JavaScirpt/CSSの言語単位がコンテキスト境界線ですかね。

細分化は正義。(脳死)

しかしご安心を。

Nuxt.jsでは簡単にそれぞれをファイル分割して読み込むことが可能です。

公式でもこの手法が紹介されています。

ソースのインポート もし *.vue コンポーネントを複数のファイルに分割したい場合は、src 属性を使って言語ブロック用の外部ファイルをインポートすることが出来ます:Vue Component の仕様 · vue-loader

今回はそのやり方と筆者のサンプルをご紹介しようと思います。

手順

それぞれを外部ファイル化

まずはそれぞれを外部ファイル化していきましょう。

HTML(pug)

まずはHTML部分を外部ファイル化していきましょう。

[adsense-responsive]

今回はindex.pugと言う名前で外部ファイル化します。

pages/index.pug
section.container
  div
    app-logo
    h1.title.scoped--sample
      | Demo
    h2.subtitle
      | Demo Project
    .links
      a.button--green(href='https://nuxtjs.org/', target='_blank') Documentation
      a.button--grey(href='https://github.com/nuxt/nuxt.js', target='_blank') GitHub

JavaScript

次にJavaScript部分index.jsと言う名前で外部ファイル化します。

pages/index.js
import AppLogo from '~/components/AppLogo.vue'

export default {
  components: {
    AppLogo
  }
}

CSS(Sass)

次にCSS部分を外部ファイル化しましょう。
今回はscss記法を使っているので、index.scssとして外部ファイル化します。

pages/index.scss
h1.scoped--sample{
  color: #F00;
}
.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.title {
  font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: $priorityColor;
  letter-spacing: 1px;
}

.subtitle {
  font-weight: 300;
  font-size: 42px;
  color: $secondaryColor;
  word-spacing: 5px;
  padding-bottom: 15px;
}

.links {
  padding-top: 15px;
}

それぞれの外部ファイルを読み込む

HTML/JavaScript/CSSの外部ファイル化が出来たらそれぞれをindex.vueから読み込みましょう。

pages/index.vue
<template lang="pug" src="./index.pug" />
<script src="./index.js" />
<style lang="scss" scoped src="./index.scss" />

[adsense-responsive]

かなりスッキリですね!

確認

では、この状態でサーバーを起動して表示確認をしてみましょう。

正常に読み込まれて表示されましたね♪

終わりに

以上のように、細分化して管理することで、修正範囲や影響範囲を絞る事が出来ました。

一つのファイルにすべて詰め込むのも悪いとは言いませんが、細かく分けた方が保守や開発がしやすくなるので、興味のある方は試してみてください♪