🌊

【2024年3月更新】 Nuxt3+Firebase Webアプリ開発手順② レイアウトの設定

2022/04/07に公開
更新情報

2024/3/22 記事更新

最新の書き方に合わせました

2023/12/22 Daisyuiを導入

モーダル作成はDaisyuiに任せたほうが良さそう

2023/10/15 TailwindCSS導入方法を更新

nuxtjs/tailwindcssを導入しました

2023/7/20 flowbiteを削りました

いい感じのデザインを素早く作るためにflowbiteは強力なツールでしたが、どうしても記述量が多く見づらくなってしまう欠点がありました。
また、モーダル作成はHTMLエレメントであるdialogを操作したほうがやりやすいので、無理してまでflowbiteを導入するメリットは少なくなり、最近はflowbiteを使うこと自体が減ったためです。

2023/3/10 flowbite、heroiconsを導入しました

  • Tailwind単独でも開発はできますが、いい感じのデザインを素早く作るにはflowbiteは強力な助けとなります。
  • flowbiteには独自のプログラムやcssが組み込まれており、スタイルをよりシンプルに書くことができます。
    例えばモーダル作成はTailwind単独で作ろうとするとかなり大変ですが、flowbiteを使うと特殊な属性を設定するだけで済みます。
  • Heroiconsはライブラリをインストールせずともsvgをコピペするだけでも使えますが、結構記述量が多くなります。

2022/11/25 nuxt.config.tsの書き方

nuxt3の正式版リリースに伴い、nuxt.config.tsの書き方を現状に合わせました

全体像

  1. Nuxt3アプリ作成〜firebaseデプロイ
  2. レイアウトの設定
  3. firestoreを使ったデータの読み取り、書き込み、更新
  4. ログイン機能の実装

スタイル関係のライブラリ

tailwindcss

tailwindcss公式の通りにインストールしても良いのですが、assets/css/tailwind.cssを設定するなど少し面倒です。

nuxtjs/tailwindjsをインストールすると、以下の2ステップで導入できますので格段に楽です
https://tailwindcss.nuxtjs.org/

// インストール
$ npm i @nuxtjs/tailwindcss

nuxt.config.tsのmodulesに以下のように追記します

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  modules: [
    '@nuxtjs/tailwindcss'
  ],
})

Daisyui

必須ではないのですが、以下の理由でスタイル用のライブラリを導入しています。

  • TailwindCssだけではどうしてもclassの書き方が長くなり、HTMLの見通しが悪くなってしまう。
  • 手軽にいい感じのサイトが作るには、予めいい感じにデザインされたUIコンポーネントを配置したほうが良い

古くはvuetify、flowbiteなどいろいろ試しましたが、2023年くらいからDaisyuiに落ち着いています。

導入方法はこちら
https://daisyui.com/docs/install/

$ npm i -D daisyui@latest

なお、nuxtjs/tailwindcssを使う場合はtailwind.config.jsファイルの作成が必要ではないのですが、Daisyuiを導入する際にはtailwind.config.jsを用意して設定を書く必要があります

// tailwind.config.jsを作成
$ npx tailwindcss init
export default {
  ・・・
  plugins: [require("daisyui")],
  daisyui: {
    themes: ["night","business"], // ここに使用するテーマを列挙
  },
}

テーマは、nuxt.config.tsに記述します

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  ・・・
  app: {
    head: {
      htmlAttrs: {
        lang: 'ja',
        "data-theme":"business" // 他に"light","cupcake"など
      },
    },
  },
})

Heroicons

どんなサイトでもアイコンは導入するので、ほぼほぼ必須みたいなものです。
(たまに痒いところに手が届かないことがあるので、もっと良いsvgアイコンライブラリがあれば導入したいところ)

https://heroicons.dev/

※こっちが公式みたいですが、svgまたはjsxでしかコピーできません。名前でコピーしたほうが便利なので、上記のdevサイトを使っています。
https://heroicons.com/

$ npm install @heroicons/vue

vueやNuxtにおいては直接名前を入れて使うこともできますし、
<component :is="~~~">の形で指定しても使えます

pages/sample.vue
<script setup lang="ts">
import { CheckCircleIcon, HomeIcon, WrenchScrewdriverIcon} from "@heroicons/vue/24/outline";

const pages = [
   {
     title:'ホーム',
     icon:'HomeIcon'
   },{
     title:'設定',
     icon:'WrenchScrewdriverIcon'
   }
]
</script>

<template>
   普通の使い方
   <CheckCircleIcon class="w-6" />
   
   componentに指定することもできる   
   <li v-for="page of pages">
     <div>{{ page.title }}</div>
     <component :is="page.icon" class="w-6" />
   </li>

</template>

ページレイアウト

TailwindCss、DaisyUi、Heroiconsを全て導入した前提でページレイアウトを作成します。

app.vue

クリックで表示
<template>
  <div class="drawer sm:drawer-open">
    <input id="my-drawer-3" type="checkbox" class="drawer-toggle" /> 
    <div class="drawer-content flex flex-col">
      <!-- Navbar -->
      <div class="w-full navbar bg-base-300">
        <div class="flex-none ">
          <label for="my-drawer-3" aria-label="open sidebar" class="btn btn-square btn-ghost sm:hidden">
            <Bars3Icon class="w-8 "></Bars3Icon>
          </label>
        </div>

        <div class="flex-1 px-2 mx-2 font-bold text-3xl">タイトル</div>

        <div class="dropdown dropdown-hover dropdown-bottom dropdown-end mr-10">

          <div tabindex="0" role="button" class="avatar">
            <div class="w-12 rounded-full">
              <img :src="currentUser.photoURL" />
            </div>
          </div>

          <ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52">
            <li class="menu-title">{{ currentUser.name }}</li>

            <li><a>ユーザー情報</a></li>
            <li><a>ログアウト</a></li>
          </ul>
        </div>

      </div>

      <!-- Page content here -->
      <NuxtPage></NuxtPage>

    </div> 
    <div class="drawer-side border-r border-r-gray-400">
      <label for="my-drawer-3" aria-label="close sidebar" class="drawer-overlay"></label> 
      <ul class="menu py-4 px-0 space-y-2 w-14 min-h-full bg-base-200">
        <!-- Sidebar content here -->
        <li v-for=" p in pages ">
          <a @click="navigateTo(p.to)">
            <component :is="p.icon" class="w-6" ></component>
          </a>
        </li>
      </ul>
    </div>
  </div>

全体レイアウトはDaisyuiのDrawerで設定

https://daisyui.com/components/drawer/

  • drawerとは、ハンバーガーメニューアイコンを押した時に左側からヌッとでてくるサイドバーのこと
  • ページ全体のレイアウトを決める要素なので、app.vueに導入するのがおすすめ
  • デフォルトではdrawerは非表示。.drawer-openを入れることで開いた状態になる

ナビバーはDaisyuiのNavbar

https://daisyui.com/components/navbar/

各ページへのリンクメニュー

const pages = [
  {
    title:'ページ1',
    icon:BellAlertIcon,
    to:'/page1'
  },{
    title:'プロフィール',
    icon:UserCircleIcon,
    to:'/profile'
  }
]

<template>
・・・
    <div class="drawer-side border-r border-r-gray-400">
      <label for="my-drawer-3" aria-label="close sidebar" class="drawer-overlay"></label> 
      <ul class="menu py-4 px-0 space-y-2 w-14 min-h-full bg-base-200">
        <!-- Sidebar content here -->
        <li v-for=" p in pages ">
          <a @click="navigateTo(p.to)">
            <component :is="p.icon" class="w-6" ></component>
          </a>
        </li>
      </ul>
    </div>
・・・
</template>

tailwindの便利な設定

theme設定

themeについて以下のように設定すると、'primary'という名前で色指定ができるようになります

tailwind.config.js
module.exports = {
  content: [
	・・・
  ],
  darkMode: 'class', // or 'media' or 'class'
  theme: {
    extend: {
      colors:{
        primary: '#0284c7' // extend下にcolorsを置くことで、追加ができる。(theme直下だと上書きしてしまう)
      }      
    },
  },
  variants: {
    extend: {},
  },
  plugins: [
    require('flowbite/plugin')
  ],
};

全コンポーネントで共通して使うスタイルの設定

@layerを使うと、スタイル設定ができる。
@applyを使うと、tailwindの書き方でスタイルを設定できる。

assets/css/tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
    h1 {
        @apply font-extrabold text-2xl
    }
}

nuxt/tailwindcssを導入している場合、assets/css/tailwind.cssを作成しなくても良いので、わざわざ作成するのも気が引ける。

なので、app/vueに全体適用のstyleとして設定しています

  <div>
    <AppBar></AppBar>
    <Drawer></Drawer>
    <NuxtPage></NuxtPage>
  </div>
</template>

<style>
h1{
  @apply text-3xl
}
</style>

参考

https://www.netlify.com/blog/2021/10/29/pairing-nuxt-3-with-tailwindcss-and-supabase/

Discussion