【Nuxt.js】ウェルカムページのレイアウト構築【sassの導入】
  • 2019.11.29に公開
  • SPA開発
  • 8. ログイン周りのレイアウト設計
  • No.2 / 4
「SPA開発」では、Nuxt.js v2.14未満が使用されています。 Nuxt.jsはv2.13~14で大きなバージョンアップがありました。それに伴い、書き方も大きく変化しています。 v2.14以上で書かれた「SPA開発」の続編は、カテゴリー「 Udemy 」 で公開しています。

今回達成すること

今回は、ログイン前のトップページに表示されるウェルカムページを作成していきます。

以下の手順で進めていきます。

  1. アプリ全体で利用する、共通タイトルの設定
  2. ログイン前のヘッダー(header.vue)の編集
  3. Nuxt.jsにsassを導入
  4. 新規会員登録ページ(signup.vue)を作成
  5. ログイン前後、共通で利用するフッター(footer.vue)の編集
  6. ログイン前のレイアウトファイル(home.vue)の編集

なお、最終的にトップページはこのようになります。

完成イメージ

2019-11-28 21-14-31

2019-11-28 21-14-46

筆者のhome.vueサンプルコードは、下記目次に記載しています。

#筆者のhome.vue

作業に移る前に

今回の記事は全てNuxt.js上での作業となります。

ターミナルは、Rails内のNuxt.jsプロジェクト(筆者の場合、myapp/frontend)に移動しておいてください。

froutend $ # ここに移動しておく

共通タイトルの設定

まず、アプリで使用する共通タイトルを設定していきます。

ヘッダーに表示したり、フッターのコピーライトに表示するアプリ名のことですね。

今のタイトルはどこから表示されているか?

2019-11-28 13-38-14

現状、筆者の場合では「frontend」という名前がページタイトルとして表示されています。

これはNuxt.jsの作成時に決めたプロジェクト名が反映されています。

どこで設定されているかというと、package.json内のnameというプロパティです。

frontend/package.json
{
  "name": "frontend",
	...
}

ここのnameを、nuxt.config.jsheadプロパティでタイトルとして設定しています。

frontend/nuxt.config.js
const config = {
  mode: 'spa',
  head: {
    title: process.env.npm_package_name || '',
    ...

つまり、package.jsonで好きな名前に書き換えて、nuxt.config.js内で取得すれば良いってことですね。

共通タイトルを書き換えて表示する

仕組みがわかったところで、package.json内の共通タイトルを書き換えましょう。

frontend/package.json
{
  "name": "demoApp", // 自由な名前でOK
	...
}

クライアント側で使えるようにenvプロパティを登録

今のままコンポーネント内でprocess.env.npm_package_nameを利用しようとしても、空の値が返されます。

何故かというと、process.envの中身はサーバー側の値であり、クライアント(ブラウザ)側からは読み込めないためです。

そこで、サーバー側の値をクライアント側でも利用できるよう、nuxt.config.jsenvプロパティを登録します。

frontend/nuxt.config.js
const config = {
	...
  
  // 追記
  env: {
    APP_NAME: process.env.npm_package_name
  }

}

この設定により、クライアント側でprocess.env.APP_NAMEという環境変数が利用できるようになりました。

共通タイトルを確認しましょう

ログイン前のヘッダーコンポーネント、header.vueを以下のように書き換えてください。

frontend/components/shared/header.vue
<template>
  <div>
    {{ appName }}
  </div>
</template>

<script>
export default {
  data: () => ({
    appName: process.env.APP_NAME
  })
}
</script>

package.jsonで指定したアプリ名が表示されます。

2019-11-28 14-18-23

ログイン前のヘッダー「header.vue」を編集する

さて、次はこんな感じ↓にログイン前のヘッダーを編集していきます。

完成イメージ

2019-11-28 17-24-47

componentsディレクトリ内のheader.vueを開いてください。

frontend/components/shared/header.vue
<template>
  <div>
    <v-app-bar
      elevation="1"
    >
      <v-toolbar-title>
        <nuxt-link
          to="/"
        >
          {{ appName }}
        </nuxt-link>
      </v-toolbar-title>

      <v-spacer />

      <v-toolbar-items
        v-for="(link, i) in links"
        :key="i"
      >
        <v-btn
          :to="link.to"
          text
          class="font-weight-bold"
        >
          {{ link.title }}
        </v-btn>
      </v-toolbar-items>
    </v-app-bar>
  </div>
</template>

<script>
export default {
  data: () => ({
    appName: process.env.APP_NAME,
    links: [
      { title: '新規会員', to: '/signup' },
      { title: 'ログイン', to: '/login' }
    ]
  })
}
</script>
  • v-app-bar

    Vuetifyのv-toolbarでも同じヘッダーを作成できますが、今回はv-app-barを採用しました。

    v-app-barは、様々なスクロールイベントを付与することができます。

    App bars - Vuetify

  • elevation="1"

    これはツールバーの影の濃さを数字で指定します。0〜24の値を指定できます。

    CSS Elevation helpers — Vuetify.js

ただ...ちょっとアプリ名がリンク色に染まってブサイクですね...。

2019-11-28 16-28-31

Nuxt.jsにsassを導入する

sassを導入してオリジナルのCSSクラスを作成しましょう。

今回は公式のインストール方法に従ってsassを導入します。

API: css プロパティ - Nuxt.js

1. node-sass と sass-loaderをインストールする

ターミナルより、sass実行に必要なモジュールをインストールします。

frontend $ yarn add node-sass sass-loader

2. main.scssファイルの作成

assets直下にcssディレクトリと、main.scssファイルを作成します。

 frontend % mkdir assets/css && touch assets/css/main.scss

assetsディレクトリの構成は以下のようになります。

assets
├── README.md
└── css
    └── main.scss

3. nuxt.config.jsにCSSファイルを登録

続いてnuxt.config.jsにmain.scssをメインCSSファイルとして登録します。

frontend/nuxt.config.js
const config = {
	...
  
  css: [
    '@/assets/css/main.scss'	// 追記
  ],
  
}

以上で設定は完了です。

これでsassが利用できるようになりました。

main.scssにオリジナルクラスを作成する

main.scssにリンクカラーを黒にするクラスを作成し、ヘッダーアプリ名の色を変更します。

frontend/assets/css/main.scss
$black: rgba(0, 0, 0, 0.87);

// commons //////////////////////////
body {
  word-wrap: break-word;
  overflow-wrap: break-word;
}
a.link-black {
  color: $black !important;
  text-decoration: none;
}
  • $black: rgba(0, 0, 0, 0.87);

    $blackには、Vuetifyのブラックと一致する色を指定しています。

header.vueにクラスを付け加える

作成したlink-blackクラスをアプリ名に付け加えましょう。

frontend/components/shared/header.vue
<template>
  ...
  <nuxt-link
    to="/"
    class="link-black font-weight-bold" <!-- 追記 -->
  >
    {{ appName }}
  </nuxt-link>

よし、これでアプリ名がブサイクではなくなりました!

2019-11-28 16-46-47

新規会員登録ページ「signup.vue」を作成する

今のままヘッダーの「新規会員」をクリックすると、ページが無いためエラーになります。

そこでsignup.vueファイルを作成します。

frontend $ touch pages/signup.vue

作成したsignup.vueを仮編集しておきましょう。

frontend/pages/signup.vue
<template>
  <div>
    新規会員登録ページ
  </div>
</template>

<script>
export default {
}
</script>

これにて「header.vue」は完成です

以上でログイン前のheader.vueは完成です。

2019-11-28 17-24-47

共通のフッター「footer.vue」を編集する

続いてfooter.vueの編集です。

完成イメージ

2019-11-28 18-16-37

frontend/components/shared/footer.vue
<template>
  <v-footer
    padless
  >
    <v-col
      class="text-center"
      cols="12"
    >
      <div class="body-2">
        &copy;{{ copyRightYear }} — <strong>{{ appName }}</strong>
      </div>
    </v-col>
  </v-footer>
</template>

<script>
export default {
  data: () => ({
    appName: process.env.APP_NAME
  }),
  computed: {
    copyRightYear () {
      const start = 2019
      const now = new Date().getFullYear()
      return (start === now) ? start : `${start} - ${now}`
    }
  }
}
</script>
  • padless

    これはfooterのpaddingを削除するVuetifyのプロパティです。

    Footer component - Vuetify

  • copyRightYear ()

    現在の年度とアプリ制作年度を比較して、コピーライトの表記を自動化しています。

    2019年の場合 => 「©2019 — demoApp」

    2020年の場合 => 「©2019 - 2020 — demoApp」

OK!完成イメージ通りのフッターが作成できましたね。

最後。レイアウトファイル「home.vue」を編集する

layputsディレクトリ内に作成したhome.vueは、ログイン前のウェルカムページになります。

よくwebアプリのトップページにある「ようこそ」や「アプリの説明」を表示するページのことです。

<v-content>タグ内に、自由にコンテンツを作成してください。

frontend/layouts/home.vue
<template>
  <v-app>
    <my-header />
    <v-content>
     <!-- ここに自由に追記 -->
    </v-content>
    <my-footer />
  </v-app>
</template>

<script>
import myHeader from '~/components/shared/header.vue'
import myFooter from '~/components/shared/footer.vue'

export default {
  components: {
    myHeader,
    myFooter
  },
  data: () => ({
    appName: process.env.APP_NAME
  })
}
</script>
  • <v-content>

    大切なのは、この<v-content>タグの中にメインコンテンツを書くということです。

    もしこのタグで囲まない場合、コンテンツの高さが足りない時にフッターが上がってきます。

    これはVuetifyのレイアウトの仕組みによるものです。

    Application service — Vuetify.js

v-contentタグで囲まない場合の悪い例

2019-11-28 20-56-41

本番環境にpushしておきましょう

さて、home.vueの編集が完了したら、Railsプロジェクトに戻ってHerokuにPushしましょう。

frontend $ cd ../
myapp $ git add -A
myapp $ git commit -m "welcome_page_layouts"
myapp $ git checkout master
myapp $ git merge login_layouting
myapp $ git push
myapp $ git push heroku

pushが完了したら元のレイアウトブランチに戻っておきます。

myapp $ git checkout login_layouting
myapp $ git branch                  
* login_layouting
  master

まとめ

さて、今回の学んだポイントをおさらいします。

  • アプリの共通タイトルはpackage.jsonnameプロパティで管理する。
  • サーバーサイドとフロントエンドで環境変数を共有したい場合は、nuxt.config.jsenvに登録する。
  • Nuxt.jsにsassを導入する時は、node-sasssass-loader モジュールをインストールする。
  • メインコンテンツは、<v-content>タグで囲む。(Vuetifyの場合)

以上となります。

お疲れでした!(長い戦いだった。。。)

さて、次回は?

さてさて、次回「新規会員登録ページ」のレイアウト構築と、メールアドレス、パスワードの入力フォームの導入を行います。

どうぞ、お楽しみに!

筆者のhome.vue

筆者のサンプルコードです。

frontend/layouts/home.vue
<template>
  <v-app>
    <my-header />
    <v-content>
      <v-parallax
        dark
        src="https://cdn.vuetifyjs.com/images/backgrounds/vbanner.jpg"
      >
        <v-row
          align="center"
          justify="center"
        >
          <v-col
            class="text-center"
            cols="12"
            sm="8"
          >
            <h1 class="display-1 mb-4">
              ようこそ!{{ appName }}へ
            </h1>

            <v-list-item
              href="https://blog.cloud-acct.com/categories/spa"
              target="_blank"
              rel="noopener noreferrer"
            >
              <v-list-item-content>
                <h2 class="subtitle-1 font-weight-medium white--text">
                  このアプリの作り方を見る
                </h2>
              </v-list-item-content>
            </v-list-item>
          </v-col>
        </v-row>
      </v-parallax>

      <v-container>
        <v-row
          justify="center"
        >
          <v-col
            class="text-center"
            cols="12"
          >
            <div>
              {{ appName }}では以下の技術を採用しています。
            </div>
          </v-col>

          <v-col
            v-for="(item, i) in cardItems"
            :key="i"
            class="text-center"
            cols="12"
            :sm="12 / cardItems.length"
          >
            <v-avatar
              :color="item.color"
              :size="(600 / cardItems.length) - 30"
            >
              <span class="white--text display-1">
                {{ item.name }}
              </span>
            </v-avatar>

            <v-card
              flat
              color="transparent"
            >
              <v-card-title class="justify-center">
                {{ item.name }} {{ item.version }}
              </v-card-title>
              <v-card-text>
                {{ item.description }}
              </v-card-text>
            </v-card>
          </v-col>

          <v-col
            class="text-center"
            cols="12"
          >
            <div>
              このアプリの作り方は、チュートリアル形式で公開されています。
            </div>
            <a
              href="https://blog.cloud-acct.com/categories/spa"
              target="_blank"
              rel="noopener noreferrer"
            >
              このアプリの作り方を見る
            </a>
          </v-col>
        </v-row>
      </v-container>
    </v-content>
    <my-footer />
  </v-app>
</template>

<script>
import myHeader from '~/components/shared/header.vue'
import myFooter from '~/components/shared/footer.vue'

export default {
  components: {
    myHeader,
    myFooter
  },
  data: () => ({
    appName: process.env.APP_NAME,
    cardItems: [
      {
        name: 'Rails',
        color: '#CC3C33',
        version: '6.0.0',
        description: 'サーバーサイドにRails APIモードを採用'
      },
      {
        name: 'Nuxt.js',
        color: '#00C550',
        version: '2.10.2',
        description: 'フロントエンドにNuxt.js SPAモードを採用'
      },
      {
        name: 'Vuetify',
        color: '#2271C6',
        version: '2.1.9',
        description: 'UIフレームワーク'
      }
    ]
  })
}
</script>
あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる。そんな方に向けた単発・短期間メンターサービスを行っています。
独学プログラマのサービス
SPA開発の投稿
1
  • 更新情報
  • /
  • #01
「Rails apiとNuxt.jsでSPA開発」のデモアプリを開発中...。【2020/05/19追記: このカテゴリーの更新を一旦終了といたします】
1
  • 今回作るアプリケーション
  • /
  • #01
Railsアプリの完成イメージ画像と作ろうと思った経緯
2
  • 今回作るアプリケーション
  • /
  • #02
今回作るRailsアプリの全体像と機能の整理
1
  • 開発環境を整える
  • /
  • #01
macにRailsをゼロからインストールする
2
  • 開発環境を整える
  • /
  • #02
Rails apiモードのプロジェクトを作成し、Gitにコミットする
3
  • 開発環境を整える
  • /
  • #03
Bitbucketに公開鍵を追加し、Railsプロジェクトをpushする
4
  • 開発環境を整える
  • /
  • #04
HerokuCLIのインストールとherokuアプリケーションの作成
1
  • RailsをHerokuにデプロイする
  • /
  • #01
Herokuのデータベース設定と開発に便利なgemを導入する
2
  • RailsをHerokuにデプロイする
  • /
  • #02
HerokuにPumaを導入するためのRailsセットアップ
3
  • RailsをHerokuにデプロイする
  • /
  • #03
Railsに"Hello"を表示してHerokuへデプロイする
1
  • RailsとNuxt.jsを共存させる
  • /
  • #01
【RailsとNuxt.jsの共存】Rails上にNuxt.jsのプロジェクトを構築しよう
2
  • RailsとNuxt.jsを共存させる
  • /
  • #02
Nuxt.jsからRailsへ、初めてのapi通信でHelloを表示しよう
3
  • RailsとNuxt.jsを共存させる
  • /
  • #03
Nuxt.jsにVuetify2.0を導入してFont Awesomeもインストールするぜ
4
  • RailsとNuxt.jsを共存させる
  • /
  • #04
初めてのRailsApiアプリの公開。Herokuにデプロイする準備と実際のデプロイまで
1
  • データベース設計
  • /
  • #01
データベースを正規化する前に、会計システムの勘定科目データを整理する
2
  • データベース設計
  • /
  • #02
会計システムのデータベース設計に挑む
1
  • バージョンアップ情報
  • /
  • #01
【ご報告】Nuxt.jsを2.10.2にバージョンアップしました
2
  • バージョンアップ情報
  • /
  • #02
【ご報告】Railsを6.0.0にバージョンアップしました
1
  • Userモデル開発
  • /
  • #01
本番環境と開発環境でRailsのSeedデータを切り替える
2
  • Userモデル開発
  • /
  • #02
Railsにユーザーテーブルを作成する【テーブル確認コマンド】
3
  • Userモデル開発
  • /
  • #03
【Rails】EachValidatorクラスを使ったEmailカスタムバリデーション【lib以下読み込み】
4
  • Userモデル開発
  • /
  • #04
【Rails】エラーメッセージの日本語化【i18nとja.ymlのセッティング】
5
  • Userモデル開発
  • /
  • #05
【Rails】開発・テスト・本番環境の全てにユーザーSeedデータ投入する
6
  • Userモデル開発
  • /
  • #06
【Rails】ユーザーモデルのバリデーションをテストする
1
  • ログイン周りのレイアウト設計
  • /
  • #01
【Nuxt.js】ログインフラグでレイアウトを切り替えるテクニック【2019/12/07追記あり】
2
  • ログイン周りのレイアウト設計
  • /
  • #02
【Nuxt.js】ウェルカムページのレイアウト構築【sassの導入】
3
  • ログイン周りのレイアウト設計
  • /
  • #03
【Nuxt.js】ログイン周りの入力フォームコンポーネント設計【2019/12/07追記あり】
4
  • ログイン周りのレイアウト設計
  • /
  • #04
【Nuxt.js】会員登録フォームを構築してサインアップページを完成させる
独学プログラマ
独学でも、ここまでできるってよ。
CONTACT
Nuxt.js制作のご依頼は下記メールアドレスまでお送りください。