🔰【初心者】Nuxt.js とFirebaseを使ってログイン機能を実装する。 その１

Qiita初投稿です。

Nuxt.jsに触れる機会があったので、備忘録として投稿させてもらいます。

##Nuxt.jsとは
Nuxt.jsとは、Vue.jsのフレームワークの１つです。

主な特徴として、

* Vue-router　:　アプリケーション内のページ遷移（ルーティング）を管理するパッケージ
* vuex　:　アプリケーション内のデータや状態の管理を行うパッケージ

などが挙げられます。

この他にも、デフォルトでSSRが行えたりと初心者にもわかりやすく非常に便利です。
SSRとは、要は
「従来のクライアント・サーバー間の処理の大部分をサーバーが担ってくれるため、処理が非常に早くなる仕組み」
程度で考えてもらっていいと思います。

ちなみに、SSRなどの概念は[この記事](https://qiita.com/amakawa_/items/e7d0720e1ab8632769bf)が非常にわかりやすかったです。

## Nuxtアプリケーションの生成
では早速、Nuxtフォルダの実装を行っていきます。

yarnのインストールが出来ていなければまず最初にこのコマンドを行なってください。

```
sudo npm install -g yarn  
```

yarnが既に入っている人は、Nuxtアプリケーションを生成しましょう。

```
yarn create nuxt-app 生成フォルダ名
```
　
　
コマンドを実行すると、めちゃくちゃ質問されます。

#### アプリケーションの名前

```
? Project name (QiitaExample) 
```
基本的にはそのままEnterでいいです。

#### アプリケーションの説明

```
? Project description (My exquisite Nuxt.js project) 
```
基本的にはそのままEnterでいいです。

#### 作者の名前

```
? Author name (Your name) 
```
ここも基本的にはそのままEnterでいいです。


####パッケージマネージャーの選択
```
? Choose the package manager (Use arrow keys)
❯ Yarn 
  Npm 
```
パッケージマネージャーにに`npm`か`yarn`のどちらを使うかを選べます。
#### UIフレームワークの選択

```
? Choose UI framework (Use arrow keys)
❯ None 
  Ant Design Vue 
  Bootstrap Vue 
  Buefy 
  Bulma 
  Element 
  Framevuerk 
  iView 
  Tachyons 
  Tailwind CSS 
  Vuetify.js 
```
UIフレームワークに何を使うかです。(今回は、`Vuetify.js`を使っていこうと思います。)
#### サーバーサイドのフレームワークの選択

```
? Choose custom server framework (Use arrow keys)
❯ None (Recommended) 
  AdonisJs 
  Express 
  Fastify 
  Feathers 
  hapi 
  Koa 
  Micro 
```

サーバーサイドのフレームワークです。
`TypeScript`などを使う際は`Express`が良いと思いますが、今回はNoneで以下行きます。

#### Nuxtモジュールの選択

```
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to inv
ert selection)
❯◯ Axios
 ◯ Progressive Web App (PWA) Support
 ◯ DotEnv
```

今回は`firebase`でサーバーと結びつけるため`DotEnv`を選択します。
（後々紹介しますが、DotEnvはサーバー情報を隠してくれるツールです。）

#### コードフォーマッターの選択

```
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to inver
t selection)
❯◯ ESLint
 ◯ Prettier
 ◯ Lint staged files
 ◯ StyleLint
```
あまりよろしくないコードや、ルールに則ってコード整形してくれるツールです。
今回は何も選択しません。

####テストフレームワークの選択

```
? Choose test framework (Use arrow keys)
❯ None 
  Jest 
  AVA 
```
これは正直違いがわかりません。（笑）
なので、今回はNoneにします。
（詳しい方は教えてくださると助かります。）


####レンダリング方法

```
? Choose rendering mode (Use arrow keys)
❯ Universal (SSR) 
  Single Page App 
```

冒頭で述べたSSRかSPAの選択が出来ます。
今回はSSRを選択します。
（SSR・SPAの概念がわからない人は[この記事](https://qiita.com/amakawa_/items/e7d0720e1ab8632769bf)がおすすめです。）

####デベロップメントツールの選択

```
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to i
nvert selection)
❯◯ jsconfig.json (Recommended for VS Code)
```
Visual Studioを使う際は入れておいたほうがいいかもです。
僕はAtomを使うので、選択をしていません。



```
🎉  Successfully created project QiitaExample

  To get started:

	cd QiitaExample
	npm run dev

  To build & start for production:

	cd QiitaExample
	npm run build
	npm run start

✨  Done in 2160.69s.
```
この画面が表示されたら無事に初期設定が終了です！

## Nuxtの実行
では早速起動してみましょう。
　
自分が作った、フォルダに移動します。

```
cd 生成フォルダ名
```
その後`npm run dev`で実行出来ます。

```
npm run dev
```

```
~:QiitaExample yourname$ npm run dev

> QiitaExample@1.0.0 dev /~/QiitaExample
> nuxt


   ╭─────────────────────────────────────────────╮
   │                                             │
   │   Nuxt.js v2.11.0                           │
   │   Running in development mode (universal)   │
   │                                             │
   │   Listening on: http://localhost:3000/      │
   │                                             │
   ╰─────────────────────────────────────────────╯

ℹ Preparing project for development                                   17:38:51
ℹ Initial build may take a while                                      17:38:51
✔ Builder initialized                                                 17:38:51
✔ Nuxt files generated                                                17:38:51

✔ Client
  Compiled successfully in 6.37s

✔ Server
  Compiled successfully in 5.58s

ℹ Waiting for file changes                                            17:38:59
ℹ Memory usage: 322 MB (RSS: 463 MB)                                  17:38:59

```

この画面が表示されれば、無事に実行出来ています。
実行中は、http://localhost:3000/ に編集中の画面が表示されます。
では、http://localhost:3000/ を確認してみましょう。

<img width="1440" alt="スクリーンショット 2020-01-20 17.54.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/657b3858-90af-a8b2-d963-dbfb75bd84d7.png">

こんな感じになるはずです。

## Nuxtのディレクトリ構造
では早速生成した、実行フォルダの中身をみていきましょう。

### assets
主に画像データなどを記述するフォルダになります。
こちらは、`webpack`モジュールとして扱うことができます。
`webpack`モジュールは、「画像データをURLとして扱えるようになるため非常に処理が早くなるもの」という認識で大丈夫だと思います。
ただし、データサイズの大きなものを扱ってしまうとかえって処理が遅くなるので、細々したものがベストです。


### components
頻繁に使うロゴや、ヘッダー、フッターなどを記述します。
ここに雛形を作っておくとアプリケーション内の`pages`、`layouts`で簡単に呼び出すことができます。


### layouts
アプリケーションの大まかな外観を決めることができます。
また基本的に`/layouts/default.vue`から、`pages`を表示させていくという動き方になります。
呼び出し方は、下のように`<nuxt />`で呼び出せます。
また、「不明なページに遷移した」などのエラー時には`layouts/error.vue`が呼び出されます。

```/layouts/default.vue
<template>
  <nuxt/>
</template>
```

### middlware
[この記事](http://lab.astamuse.co.jp/entry/2019/05/29/114500)に良い画像があったので使わせてもらいます。
<img width="779" alt="スクリーンショット 2020-01-20 18.35.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/fd879384-08d7-0a73-c4a4-247e5d18e7f4.png">

このように、`pages`や`layouts`がレンダリング（ページが生成）される度に、その前に呼び出せれる処理を記述するディレクトリになります。
ここに、リダイレクト処理などを記述すると綺麗に機能します。

### pages
メインで記述していく部分になります。
`layouts`に表示してもらうページをここに記述します。
また冒頭で述べた通り、`Vue-router`が標準装備されているため、特にルーティングなどは気にしなくても大丈夫です。

###plugins
外部モジュールなどを詳しく記述することができます。
今回は`firebase`の情報ををここに記述します。
ただし、使う際は、`nuxt.config.js`の`modules`にも記述する必要があります。

###static
assetsと同じように、画像データを記述するフォルダです。
こちらは`webpack`モジュールとしては扱わないので、`asset`で扱わないような大きなデータサイズのものなどをメインに記述していきます。

###store
アプリケーション内のデータや情報の保持・操作を行うフォルダです。
標準装備されているVuexの領域でもあります。
今回はログイン状態やパスワードなどを記述していきます。

###nuxt.config.js
このファイルにこのアプリケーションの内容をざっくり記述していきます。
またこのファイルをいじると、`npm run dev`が止まるもしくは不具合がでるので、ここをいじったあとはもう一度ビルドをした方がいいです。

##pagesやlayoutsの記述方法
基本的なUIの記述方法は、HTMLとCSSとJSがひとまとまりになったようなものです。
つまり以下のようになります。

```hogehoge.vue
<!-- 要はHTML -->
<template>
 <v-app>
  <v-content>
   <!-- ここにいっぱいコンテンツを書いていく -->
  </v-content>
 </v-app>
</template>

<!-- 要はJS -->
<script>
//methodsやらなんやら
</script>

<!-- 要はCSS -->
<style>
/* templateにあるコンテンツの見た目を変える */
</style>
```
では１つずつ見ていきましょう。
###template
上にあるように`HTML`のような働きをします。
今回はUIフレームワークに`Vuetify`を採用しているため、`<v-app>`で全ての`Vuetifyコンポーネント`を囲む必要があります。ここで囲んでいないとそれぞれのコンポーネントが予期せぬ挙動をします。
ただし、これは`layouts/default.vue`で`<nuxt />`を囲んでおけば、わざわざ`pages`に記述する必要はないです。

そのほかの基本的なコンポーネントのことは[公式](https://vuetifyjs.com/ja/)をご覧ください。

###script
ここでは`JavaScript`の働きのように、そのページのみの関数などを記述し挙動を決定します。
またプラグインを`import`をするのもここです。
まずは例の全体像をあげます。

```pages/hogehoge.vue
<script>
import firebase from "~/plugins/firebase.js";
export default{
  data() {
    return {
        mailAddress: '', 
        password: '',　
    }
  },
  methods: {
    pushBtn: function() {
      console.log("ボタン押したよ。")
    },
    login: function() {
      firebase.auth().signInWithEmailAndPassword(this.mailAddress, this.password)
       .then(user => {
        this.$store.commit('loginState', this.mailAddress, this.password);
        this.$router.push("top");
      }).catch((error) => {
        this.valid = true;
      });
    },
  },
  created() {
    console.log("createしたよ。")
  },
};
</script>
```
このように`data`・`methods`・`created`を今回は多用します。
では１つずつ見てみましょう。

####data
そのページのみで使う変数を定義します。

```pages/hogehoge.vue
<script>
export default{
 data() {
     return {
         mailAddress: '', 
         password: '',
     }
   },
....
}

</script>
```
ここは多分大丈夫でしょう。

####methods
そのページで使う関数を定義します。

```pages/hogehoge.vue
<script>
export default{
 ....
 methods: {
    pushBtn: function() {
      console.log("ボタン押したよ。")
    },
    login: function() {
      firebase.auth().signInWithEmailAndPassword(this.mailAddress, this.password)
       .then(user => {
        this.$store.commit('loginState', this.mailAddress, this.password);
        this.$router.push("top");
      }).catch((error) => {
        this.valid = true;
      });
    },
  },
...
}
</script>
```
この例では`pushBtn`という関数と`login`という関数が定義されています。
次回以降で触れていくのでまだ気にしなくてもいいのですが、`login`では、正常に作動すると`store`に定義された`loginState`という`mutations`を呼び出し、且つ`pages/top.vue`という場所に画面遷移するような関数になっていることがわかります。
また、この`this.$router.push("行き先のパス")`という書き方が、基本的な`vue-router`の書き方になるので、覚えておきましょう。

####created
これは「ページができる(create)されたのちに一回一回作動するもの」という考え方で概ね大丈夫です。
詳しくは[公式のライフサイクル](https://jp.vuejs.org/v2/guide/instance.html)をみてみてください。

```pages/hogehoge.vue
<script>
export default{
....
 created() {
    console.log("createしたよ。")
  },
}
</script>
```
つまり今回では、このページが表示されるたびに「createしたよ。」と`console`されます。

以上３つ紹介しましたが`mounted`など他にも重要なものがあります。
気になる方は色々調べてみてください。
一応[公式](https://jp.vuejs.org/v2/api/index.html)を貼っておきますが、あまりわかりやすくはないです。

##まとめ
今回はざっくばらんにNuxt.jsについて説明させてもらいました。
次回から、具体的な記述の仕方を書いていこうと思います。

また、間違えている点があれば是非教えてください！！
次回は[こちら](https://qiita.com/sychocola1/items/e7ca6a0bac16a9f8f3fa)からどうぞ