53
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nuxt+Vuetify+FirebaseでWEBアプリを開発する

Last updated at Posted at 2019-04-21

はじめに

「WEBアプリをサクッと開発してサクッと公開したい」と思い、実際にやってみました。
その備忘録です。

更新情報

  • 2019/4/27 ログインの実装まで
  • 2019/5/24 ミドルウェアの実装まで

Vue.jsとは

簡単に言うと「JavaScriptのフレームワークのひとつ」です。
ReactやAngularと同列のやつですね。
(正確にはReactはライブラリらしいですが)

Nuxtとは

Vue.jsのフレームワークです。
vue-routerやvuexなどが最初から入ってます。
開発をviewだけに集中することができるらしいです。
(Nuxt.jsという名前はReactのフレームワークであるNext.jsから来てるらしい(パクリw)

Vuexとは

Vue.jsアプリケーションのためのVuexとは状態管理のためのライブラリです。
コンポーネント間での値の受け渡しがわかりやすくなります。

Vuetifyとは

VuetifyとはVue.jsで使えるマテリアルデザインのフレームワークです。
デザインフレームワークはいろいろありますが、個人的にこれがビビッときました。

Firebaseとは

Googleが提供しているmBaaSです。
バックエンドをまるっと請け負ってくれます。
かつ無料である程度のことができます。

今回使うFirebaseの機能

Authentication

メールアドレスとパスワードで認証を管理します

Firestore

DBとして使います

Storage

画像を保存します

Hosting

デプロイします

環境

  • macOS Mojave 10.14.2
  • git 2.17.2
  • yarn v1.13.0
  • node v10.15.0
  • npm 6.4.1
  • npx 6.4.1
  • firebase-tools 6.7.0
  • Nuxt.js 2.4

プロジェクトの作成

npx create-nuxt-app project_name(プロジェクト名は適宜)

npxはnpmのバージョンが5.2.0以上じゃないと使いないそうです。

質問

  1. プロジェクト名は? → デフォ
  2. プロジェクト概要は? → デフォ
  3. サーバのフレームワークは? → none
  4. axiosなどをインストールしますか? → しない(必要であれば後で入れる)
  5. UIフレームワークは? → vuetify
  6. テストフレームワークは? → none(必要であれば後で入れる)
  7. レンダリングモードは? → SPA
  8. 名前は? → デフォ
  9. パッケージマネージャーは? → yarn

完了!

yarn dev

ローカルで動作確認する。(http://localhost:3000/

めっちゃリッチなサンプルページが表示されたww

参考

git管理下にする

cd project_name
git init
git remote add origin https://github.com/user_name/project_name.git
git add README.md
git commit -m 'first commit'
git add .
git commit -m 'create-nuxt-app'
git push origin master

完了!

Firebaseのプロジェクト作成

ここでプロジェクトを作成する。

Firebaseとプロジェクトを紐付ける

firebase-toolsをインストールする

yarn global add firebase-tools

npmの人はこっち

npm i -g firebase-tools

yarnのグローバルインストールモジュール確認(firebase-toolsが入ったか確認するため)

yarn global list --depth=0

firebase-toolsのバージョン確認

firebase -V or firebase --version (firebase -v は出来ない...)

6.7.0が最新だった

firebaseにログインする

firebase login

プロジェクトにfirebaseを導入する

firebase init

質問

  1. 使う機能は? → 一旦hostingのみ
  2. Firebaseプロジェクトは? → (上で作成したプロジェクト)
  3. 公開ディレクトリは? → dist(Nuxt.jsがデフォルトでdistなので)
  4. Configure as a single-page app? → どっちでもいい

.firebasercとfirebase.jsonファイルが生成される

firebaseにデプロイする

nuxtの静的ページを作成する

yarn generate

dist/ができるはず

deployする

firebase deploy

URL(https://project_name.firebaseapp.com/ )が発行されて、デプロイ完了!

ここまで、プロジェクトの作成から公開までやってきました。

参考

FirebaseとNuxtを紐付ける

firebaseライブラリをyarnでローカルに入れる

yarn add firebase

(.firebaseはgitignoreした)

pluginsディレクトリ下にfirebase.jsというファイルを作成する

touch plugins/firebase.js
firebase.js
import firebase from 'firebase'

if (!firebase.apps.length) {
  firebase.initializeApp({
    apiKey: process.env.FIREBASE_API_KEY,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN,
    databaseURL: process.env.FIREBASE_DATABASE_URL,
    projectId: process.env.FIREBASE_PROJECT_ID,
    storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID
  })
}

export default firebase

中身はこんな感じ。

SPAが呼び出された時点でfirebaseを読み込みたいので、nuxt.config.jsのpluginsに追記

nuxt.config.js
plugins: [
  '@/plugins/firebase.js'
]

環境変数をプロジェクトから切り離すため、.env.templateを作成する

..env.template
FIREBASE_API_KEY=
FIREBASE_AUTH_DOMAIN=
FIREBASE_DATABASE_URL=
FIREBASE_PROJECT_ID=
FIREBASE_STORAGE_BUCKET=
FIREBASE_MESSAGING_SENDER_ID=

.envファイルを作成して、firebaseの環境変数をコピペする

..env
FIREBASE_API_KEY=****
FIREBASE_AUTH_DOMAIN=****
FIREBASE_DATABASE_URL=****
FIREBASE_PROJECT_ID=****
FIREBASE_STORAGE_BUCKET=****
FIREBASE_MESSAGING_SENDER_ID=****

README.mdに.envを作成するように追記

README.md

# create .env file
cp .env.template .env

環境変数を読み込むようにするためにモジュールを追加

yarn add @nuxtjs/dotenv

nuxt.config.jsに追記

nuxt.config.js
modules: [
  '@nuxtjs/dotenv'
]

参考

https://note.mu/yoneapp/n/n7037373c0b76
https://chatboxinc.wordpress.com/2018/03/26/nuxt_js_with_dotenv/

FirebaseでAuthenticationの設定

Authenticationから「メールとパスワード」を有効にする。

ユーザ追加でテストユーザを作成しておく。

(後に独自ドメインを使う時に承認済みドメインに追加することを忘れない!)

vue-persistedstateの導入

vuexはリロードすると値が消えてしまうため、vuex-persistedstateを導入したほうがいいらしい

yarn add vuex-persistedstate

pluginsディレクトリ下にpersistedstate.jsを作成

persistedstate.js
import createPersistedState from "vuex-persistedstate";

export default ({store, isHMR}) => {
  if (isHMR) return;

  if (process.client) {
    window.onNuxtReady((nuxt) => {
      createPersistedState()(store); // vuex plugins can be connected to store, even after creation
    });
  }
};

nuxt.config.jsに追記

nuxt.config.js
plugins: [
    { src: "~plugins/persistedstate.js", ssr: false }
  ]

core-jsのインストール(エラー対処)

なんかyarn devするとエラーが出た。
core-jsの2系を入れろとのこと。

というわけで、入れる...

yarn add core-js@2

とりあえず、yarn.locknode_modulesを削除してモジュールを入れ直す

rm -rf node_modules
rm yarn.lock
yarn install

動いた。(ここのissueでまとめられてる→https://github.com/nuxt/nuxt.js/issues/5313)

参考

ログイン機能の実装

pagesディレクトリ下にlogin.vueを作成

login.vue
<template>
  <div>
    <v-container fluid fill-height>
      <v-layout align-center justify-center>
        <v-flex xs12 sm8 md4>
          <v-card>
            <v-toolbar>
              <v-toolbar-title>Login</v-toolbar-title>
            </v-toolbar>
            <v-card-text>
              <v-form>
                <v-text-field
                  v-model="email"
                  :counter="32"
                  label="email"
                  prepend-icon="email"
                ></v-text-field>
                <v-text-field
                  v-model="password"
                  :append-icon="show_password ? 'visibility' : 'visibility_off'"
                  :type="show_password ? 'text' : 'password'"
                  :counter="32"
                  label="password"
                  prepend-icon="lock"
                  @click:append="show_password = !show_password"
                ></v-text-field>
              </v-form>
            </v-card-text>
            <v-card-actions>
              <v-btn
                flat
                v-on:click="gotoSignup"
              >SIGNUP</v-btn>
              <v-spacer></v-spacer>
              <v-btn
                v-on:click="doLogin"
              >LOGIN</v-btn>
            </v-card-actions>
            <hr>
            <v-spacer></v-spacer>
            <v-btn
              flat
              v-on:click="gotoResetPassword"
            >パスワードを忘れたかたはこちら</v-btn>
          </v-card>
        </v-flex>
      </v-layout>
    </v-container>
  </div>
</template>

<script>
import firebase from '~/plugins/firebase'

export default {
  data() {
    return {
      email: '',
      password: '',
      show_password: false,
    }
  },
  methods: {
    doLogin() {
      firebase.auth().signInWithEmailAndPassword(this.email, this.password)
        .then(user => {
          this.$router.push("/")
        }).catch((error) => {
          alert(error)
        })
    },
    gotoSignup() {
      this.$router.push("/signup")
    },
    gotoResetPassword() {
      this.$router.push("/reset-password")
    }
  }
}
</script>

とりあえずこんな感じ。

pagesディレクトリ下にsignup.vuereset-password.vueを作成しておく。(中身は適宜)

firebase.auth().signInWithEmailAndPassword(this.email, this.password)

ここでfirebaseの認証をしている。

上で作成したユーザのメールアドレスとパスワードで認証ができるはず。

参考

storeの作成

storeでuserの情報を管理したいので、Nuxtに入っているVuexで状態管理をする。

Vuexのコンセプト(簡単に)

State, Mutations, Actionを簡単に抑えておく。

State

stateとはstoreで管理している状態のことを言う。
Mutations以外から更新されることは無い。
Stateを取得するためにはgettersを使う。

Mutations

stateを更新するにはMutationsからcommitをする。
Mutationsは同期処理でなければならない。

Actions

データの加工や非同期処理はActionsで行い、Mutationsからcommitして更新をする。
Actionsの呼び出しにはdispatchをする。

storeの作成

storeディレクトリ下にuser.jsを作成する。

user.js
export const state = () => ({
  user: null,
  info: null,
})

export const mutations = {
  setUser (state, payload) {
    if (payload) {
      state.user = payload
    } else {
      state.user = null
    }
  },
  setInfo (state, payload) {
    if (payload) {
      state.info = payload
    } else {
      state.info = null
    }
  },
}

export const actions = {
  setUser ({ commit }, payload) {
    commit('setUser', payload)
  },
  setInfo ({ commit }, payload) {
    commit('setInfo', payload)
  },
}

export const getters = {
  user: state => {
    return state.user
  },
  info: state => {
    return state.info
  },
}

ミドルウェアの作成

middlewareディレクトリ下にauthenicated.jsを作成する。

authenicated.js
import firebase from '~/plugins/firebase'

export default function ({ store, route, redirect }) {
  firebase.auth().onAuthStateChanged(user => {
    if (!user) {
      redirect('/account/login')
    } else {
      store.commit('user/setUser', {
        uid: user.uid,
        email: user.email,
        username: user.displayName,
        userImage: user.photoURL,
      })
    }
  })
}

こんな感じで。

コンポーネントのexport default内で(dataやmethodsと同列)、middleware: 'authenticated',を記述すると動く。

おわりに

ここまでで、プロジェクトの作成からFirebase認証でログイン機能の実装、ミドルウェアの実装までを行ってきました。
次はheaderやfooterのlayoutを作成したり、storeを使って値を参照したりしようと思います。

53
52
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?