🧑‍💻

Nuxt勉強会を開催したので、資料を公開してみる

2022/03/20に公開

はじめに

フロントエンドエンジニアとして働き約2年弱経過したのですが、友人から最近のWeb開発について教えて欲しいと相談を受けました。
一人で黙々と自主学習をするよりも、人に教えるために勉強した方が知識が定着できるとの事だったので、改めてJSフレームワークについて勉強した上でWeb勉強会を開催しました。

今回はその際の資料を精緻化したのでZennに公開します。

Web勉強会

目標

microCMS&Nuxt.js&NetlifyでJamstackなwebサイトをつくる

▼参考
https://blog.microcms.io/nuxt-microcms-netlify-portfolio/

成果物

https://masaki-kitahara.work/

目次

  • 最近のフロントエンド開発環境について知る
    • タスクランナーを使ったWeb開発
    • JSフレームワークが流行ってる
    • SSG・SPA・SSR
  • 目標を達成するための技術について知る
    • Nuxt.jsでできること
    • Netlifyでできること
    • microCMSでできること
  • Nuxtの環境構築
  • Nuxtの機能紹介
    • slot
    • props
    • $emit
  • Vuexを理解する
    • Vuexとはなにか
    • データのサイクルについて
  • コンポーネント設計
    • JSフレームワークにおけるコンポーネントとは
    • コンポーネント設計の手法
  • microCMSからjsonを取得する
  • Netlifyにデプロイしよう
  • 勉強会に参加した友人の感想
  • 所感

最近のフロントエンド開発環境について知る

タスクランナーを使ったWeb開発

GulpやWebpackを用いて開発を効率化するのが流行っている。

これまでの開発

htdocs
    ├── css
    │   └── style.css
    ├── img
    │   └── hoge.png
    ├── index.html
    └── js
        └── script.js

各ファイルにベタ書き

最近の開発

├── README.md
├── gulpfile.js
├── htdocs
│   ├── assets
│   │   ├── images
│   │   │   └── dummy.png
│   │   └── styles
│   │       └── app.css
│   └── index.html
├── package-lock.json
├── package.json
├── src
│   ├── html
│   │   ├── _foundation
│   │   │   └── _default.pug
│   │   └── index.pug
│   ├── scripts
│   │   ├── app.js
│   ├── static
│   │   └── images
│   │       └── dummy.png
│   └── styles
│       ├── _layout
│       │   └── index.styl
│       ├── _object
│       │   ├── _component
│       │   │   ├── _sample.styl
│       │   │   └── init.styl
│       │   ├── _project
│       │   │   └── init.styl
│       │   ├── _utility
│       │   │   └── support.styl
│       │   └── index.styl
│       └── app.styl

ファイル数が大量になりました。
srcディレクトリの中で開発したものをgulpやwebpackでコンパイルしてhtdocsに吐き出す。

JSフレームワークが流行っている

Vue.js React.js jQuery
JavaScriptをもっと効率的に!

JSフレームワークの種類

Vue.jsのフレームワーク

  • Nuxt.js

React.js

  • Next.js
  • Gatsuby.js

SSG・SPA・SSRについて知る

以下の記事が個人的に概念を理解するのにオススメです。
https://shimablogs.com/spa-ssr-ssg-difference

目標を達成するための技術について知る

Netlify

https://www.netlify.com/

- 静的サイトのホスティングサービス
- Gitと連携して自動デプロイができる
- サーバーレス関数が使える

mircoCMS

https://microcms.io/

  • APIベースのCMS
  • サーバー不要でCMSが実装できる

▼JamStackの概念については以下の記事を参考
https://qiita.com/ozaki25/items/4075d03278d1fb51cc37

Nuxt.js

vue.jsのフレームワーク

  • 自分の作成したいサイトに合わせてカスタマイズができる
  • シームレスな画面遷移
  • データの状態管理

Nuxt.jsの開発環境構築

1.Gitのリポジトリを作ってローカルへクローン
2.create nuxt-app

$ npm create nuxt-app my-portfolio

create-nuxt-app v4.0.0
✨  Generating Nuxt.js project in my-portfolio
? Project name: my-portfolio
? Programming language: JavaScript
? Package manager: Npm
? UI framework: None
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Linting tools: 
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Static (Static/Jamstack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? What is your GitHub username? masaki kitahara
? Version control system: Git

3.pugとstylusをインストール
※せっかくなので、htmlとcssのテンプレートエンジンも使ってみよう

$ npm i pug pug-loader pug-plain-loader stylus stylus-loader@3.0.2 @nuxtjs/style-resources
nuxt.config.js
 // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
    '~/assets/stylus/global/index.styl'
  ],
  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    '@nuxtjs/style-resource',
  ],
  styleResources: {
    stylus: './assets/stylus/resources/index.styl'
  },

Nuxtの機能

  • Components

components ディレクトリには、Vue.js コンポーネントが含まれています。コンポーネントは、ページのさまざまな部分を構成するものであり、再利用して、ページ、レイアウト、さらには他のコンポーネントにインポートすることができます。

参考: https://nuxtjs.org/ja/docs/directory-structure/components/

  • slot
    • 子コンポーネントに対してテキスト等の要素を渡す
  • props
    • 子コンポーネントにいろんな情報を渡す
  • $emit
    • 子コンポーネントから親コンポーネントに対して変更を渡す
Sample.vue
<template lang="pug">
  .page-wrapper
    h1 slotとpropsについて
    .page-inner
      Button(v-slot:text :color='buttonColor' v-on:clickEvent="alert($event)") Hello Nuxt!
      NuxtLink(to="/about") 
        Button(v-slot:text) about
</template>

<script>
import Button from '~/components/Atoms/Button'
export default {
  // componentsを使うには宣言する必要があるよ
  components:{
    Button,
  },
  // 定数
  data: () => ({
    buttonColor: 'red',
  }),
  methods:{
    alert(event){
      alert(event)
    }
  }
}

</script>

<style lang="stylus" scoped>
.page-wrapper
  +pc()
    width 60%
  +sp()
    width 50%
.page-inner
  margin 30px 10px
  display flex
  
</style>
components/Atoms/Button.vue
<template lang="pug">
  button.a-button(:class="changeColor(color)" @click="send()") 
    slot(name="text")
</template>

<script>
export default {
  props: {
    color:{
      type:String,
      default:"gray"
    }
  },
  data: () => ({
    clickData: "click!"
  }),
  methods:{
    changeColor(str){
      if(str === "red") return "is-red"
    },
    send(){
      this.$emit("clickEvent",this.clickData)
    }
  }
}

</script>

<style lang="stylus" scoped>
.a-button
  width 200px
  padding 15px 30px
  color #fff
  font-weight bold
  background-color gray
  border-radius 30px
  margin-right 20px
  &.is-red
    background-color red
</style>

Vuexを理解する

Vuexとは何か

Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。 これは予測可能な方法によってのみ状態の変異を行うというルールを保証し、アプリケーション内の全てのコンポーネントのための集中型のストアとして機能します。

引用元:https://vuex.vuejs.org/ja/

超簡単に言うと、アプリケーション全体に関わるデータを管理するライブラリの事

データサイクルについて

上記のデータサイクルに沿って、Stateがどのように管理されるのかを表で見てみる

データを使う場所 データの受け渡しを依頼する関数 データを受け取る関数
Vue Components this.$store.dispatch(受け渡し先関数名, データ) this.$store.getters[state.データ名]
Actions context.commit(受け渡し先関数名, データ) 関数名(context,payload)
Mutations 関数名(state,payload)

NuxtでStateの管理をする場合は/store/index.jsで行う
※NuxtのStoreはクラシックモードとモジュールモードがあるが今回はクラシックモードでやります。
https://develop365.gitlab.io/nuxtjs-2.8.X-doc/ja/guide/vuex-store/

store/index.js

stroe/index.js
// stateを宣言する
export const state = () => ({
  appText:"hoge"
});

// Vue Componentsからデータを受け取って Mutationsにデータを引き継ぐ
export const actions = {
    getAppText({commit}, payload){
        commit("setAppText", payload)
    }
}

// Actionsからデータを受け取って Stateにデータを格納する
export const mutations = {
  setAppText(state,payload){
    state.appText = payload
  }
}

// データをVue Componentsに渡す
export const getters = {
  appText: state =>{
    return state.appText
  }
}

Vue Components

Components.js
<template lang="pug">
    .p-text {{appText}}
    button(@click="changeText()")
</template>
<script>
export default {
  data: () => ({
    text:"fuga"
  }),
  computed:{
      // Storeの変更を受け取る
      appText(){
          this.$store.getters['appText']
      }
  }
  methods: {
      // Actionsにデータを渡す
    changeText(){
        this.$store.dispatch(getAppText,this.text)
    }
  }
}
</script>

参考:https://qiita.com/beanzou/items/09bcbb86ae3e09cbec8f

コンポーネント設計

JSフレームワークにおけるコンポーネントとは

JSフレームワークを使ってSPAを作成する際には大きく分けて以下の2つの要素が必要です。

  • ページを表示するためのコンポーネント
  • UIを表現するための大小様々なコンポーネント

ページを表示するためのコンポーネント

SPAやSSRのサイトが表示されるためには、初回ローディング時にブラウザ側のJSやサーバー側のJSを実行してDOMを生成させる必要があります。
Nuxt.jsなどのJSフレームワークはページの切り替えをルーティング機能によって切り替えています。
そのため、各ルーティングで読み込むためのコンポーネントファイルが必要になります。

UIを表現するための大小様々なコンポーネント

前述したページを表示するためのコンポーネントの中に複数のコンポーネントを記述してページを再現していきます。

どのようにページを構成していくかは、React公式ドキュメントを参照するのが良いです。
参考:https://ja.reactjs.org/docs/thinking-in-react.html

コンポーネント設計の手法

AtomicDesign

UIを5つの粒度で定義し、それらを組み合わせてWebページを構成するデザインシステム
参考:https://bradfrost.com/blog/post/extending-atomic-design/

AtomicDesignの構成要素

  • Atoms
  • Molecules
  • Organisms
  • Template
  • Pages

Atoms

UIを構成するための最小単位

  • Button
  • font
  • label
  • input
  • select

Molecules

Atomsを組み合わせて作成する構成物

  • 検索ボタン

Organisms

AtomsやMoleculesを組み合わせる有機体

  • Header
  • Footer

Template

Atoms・Molecules・Organismsを組み合わせて、サイト全体の構成を作成する

Pages

テンプレートに独自のコンテンツを流し込んだもの

使用例

リリースしたポートフォリオサイトにAtomicDesignを組み込むと以下のような設計になりました。

※開発するアプリケーションによってコンポーネント設計の考え方は変化します。正解はありません。

microCMSからjsonを取得する

以下の記事を参考にapiを叩いてみよう
https://blog.microcms.io/nuxt-microcms-netlify-portfolio/

Netlifyにデプロイしよう

以下の記事で詳しく記載しているので、こちらを参照しましょう。
gatsby.js + netlifyでお問い合わせフォーム付きの静的サイトを作ってみた

勉強会に参加した友人からの感想

実務経験で学んだ内容を初心者にわかりやすく教えてくれる内容
北原もゼロからフロントエンジニアになったため、躓くポイントやバグの出やすい箇所を理解しているので、初心者にとっては優しい世界でWebページ作成を行うことができた。
いままでベタ打ちWebサイトしか作っていなかったので、Componentの概念やAtomicDesignの理解もできて、今後自分で何かしらのWebページを製作するときは非常に役立つものであった。

所感

想像以上に自分の知っている事を他人に教えるのは難しいと感じました。
今回、相手が気の知れる友人だった事もあり、砕けた雰囲気で進行することができましたが、もしこれから初対面や別の立場の人に教える場合は、言葉遣いや相手がどのくらいの理解度か様子を見た上で進行する必要があると感じました。

一人で黙々と自主学習をするよりも、人に教えるために勉強した方が知識が定着できるとの事

一番最初に記載した通り、明らかに知識が身についたのは確かです。
今後も機会があれば、定期的に勉強会を開催したいです。

Discussion