6
8

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 1 year has passed since last update.

Nuxt3 でプロジェクトを作成するときのメモ (ついでにVite, HMR, Bootstrap5, icons)

Last updated at Posted at 2022-09-09

nuxt-3.0.0 を使用する前提です。

結論

上のページを読めばできます。がしかし、他のモジュールを使おうとすると、微妙に説明が足りないので、以下で補完します。

バージョンなど

$ npm -v
8.19.1
$ yarn -v
1.22.19
$ node -v
v16.16.0
$ nuxi -v
Nuxi 3.0.0-rc.9

プロジェクト作成

$ nuxi init nuxt3-firebase-bootstrap-sample
$ cd nuxt3-firebase-bootstrap-sample
$ yarn
$ yarn dev

これだけです。TS はデフォルトで対応です。

image.png

HMR (Hot Module Reload)

builder はデフォルトで vite になっています。HMR はデフォルトではオンではないようです。下記設定で、オンになります。

nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'

// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({

    vite: {
        server: {
            watch: {
                usePolling: true
            }
        },
    }
})

これでオンになります。これで更新が爆速になります。

ルーティングのテスト

pages というフォルダを作って、その下に index.vue, sample.vue ファイルを作ります。App.vue は下記のようにします。

App.vue
<template>
  <div>
    <NuxtPage />
  </div>
</template>

div なしでルートに <NextPage/> を置くとエラーになります。

pages/index.vue/ のパスに対応します。/index でも読めます。

pages/index.vue
<template>
    <div>
        <h1>Top Page!</h1>
        <NuxtLink to="/sample">Sample page</NuxtLink>
    </div>
</template>

image.png

pages/sample.vue/sample のパスに対応します。

pages/sample.vue
<template>
    <div>
        <h1>Sample Page!</h1>
        <NuxtLink to="/">Top page</NuxtLink>
    </div>
</template>

image.png

Bootstrap5

モジュールをインストールします。

$ yarn add bootstrap @popperjs/core bootstrap-icons

nuxt.config.ts に追記します。アイコンを使わない場合は、bootstrap-icons は不要です。

nuxt.config.ts
export default defineNuxtConfig({
    css: [
        "bootstrap/dist/css/bootstrap.min.css",
        "bootstrap-icons/font/bootstrap-icons.css"
    ],
    ...
}

これであとは普通に Bootstrap を使えます。

上記のサンプルのページを作ってみた例を示します。

app.vue
<template>
<div>
  <header>
    <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Top navbar</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarCollapse">
          <ul class="navbar-nav me-auto mb-2 mb-md-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
            </li>
          </ul>
          <form class="d-flex">
            <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
            <button class="btn btn-outline-success" type="submit">Search</button>
          </form>
        </div>
      </div>
    </nav>
  </header>
  <main>
    <NuxtPage />
  </main>
</div>
</template>

pages/index.vue

pages/index.js
<template>
  <div class="bg-light p-5 rounded">
    <h1>Navbar example</h1>
    <p class="lead">This example is a quick exercise to illustrate how the top-aligned navbar works. As you scroll, this navbar remains in its original position and moves with the rest of the page.</p>
    <NuxtLink type="button" class="btn btn-primary" to="/sample">Go To Sample</NuxtLink>
  </div>
</template>

image.png

pages/sample.vue

このページはアイコンのテストも兼ねてます。

pages/sample.vue
<template>
<div class="bg-light p-5 rounded">
    <p class="h1">Sample Page</p>
        <i class="bi bi-house-fill" 
            style="font-size: 2.5rem; color: black;"></i>
        <NuxtLink 
            class="btn btn-primary mb-3 ms-2" role="button" type="button"
            to="/">Top page</NuxtLink>
</div>
</template>

image.png

アイコンを追加したときは、ブラウザのリロードが必要です(多分)。

map ファイルがないというエラーが出るときは、プロジェクトのルートフォルダで下記のようにします。

$ mkdir public
$  ln -s ./node_modules/bootstrap/dist/css/bootstrap.min.css.map ./public

Material Design Icons

MDI を使用する方法として、nuxt.config.ts に CSS を追加してフォントとして使う方法と、個別に import して SVG として使う方法があります。後者のほうが、ファイルサイズは小さくなります。

nuxt.config.ts にCSS を追加

フォントをインストールします。

$ yarn add @mdi/font

nuxt.config.ts に CSS を追記します。

nuxt.config.ts
export default defineNuxtConfig({
    css: [
        "@mdi/font/css/materialdesignicons.css"
    ],
    ...
}

これで、下記のようなかんじでつかえます。

sample.vue
<i class="mdi mdi-home" style="font-size: 2.5rem; color: black;"></i>

例:

pages/sample.vue
<template>
<div class="bg-light p-5 rounded">
    <p class="h1">Sample Page</p>
        <i class="bi bi-house-fill" 
            style="font-size: 2.5rem; color: black;"></i>
        <i class="mdi mdi-home"
            style="font-size: 2.5rem; color: black;"></i>
        <NuxtLink 
            class="btn btn-primary mb-3 ms-2" role="button" type="button"
            to="/">Top page</NuxtLink>
</div>
</template>

image.png

この方法はお手軽です。ただし、CSS 全体を出力ファイルに組み込むので、ファイルサイズは大きくなります。フォントを追加したときは、ブラウザのリロードが必要です(多分)。

個別に import する

モジュールを追加します。

$ yarn add @mdi/js

個別にインポートして、SVG の path として使います。

src/sample.vue
<template>
<div class="bg-light p-5 rounded">
    <p class="h1">Sample Page</p>
        <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
            width="64" height="64" viewBox="0 0 32 32">
            <path :d="mdiHomePath"></path>
        </svg>
        <NuxtLink 
            class="btn btn-primary mb-3 ms-2" role="button" type="button"
            to="/">Top page</NuxtLink>
</div>
</template>
<script>
import { mdiHome } from '@mdi/js';
export default {
    data: () => ({
        mdiHomePath: mdiHome
    })
}
</script>

image.png

svg としてレンダリングされるので、サイズや表示位置、色などかなり自由度高く設定できます。また、全体のファイルサイズも(かなり)小さくなります。

<script setup> で書く場合は下記です。

pages/sample.vue
<template>
<div class="bg-light p-5 rounded">
    <p class="h1">Sample Page</p>
        <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
            width="64" height="64" viewBox="0 0 32 32">
            <path :d="mdiHome"></path>
        </svg>
        <NuxtLink 
            class="btn btn-primary mb-3 ms-2" role="button" type="button"
            to="/">Top page</NuxtLink>
</div>
</template>

<script setup>
import { mdiHome } from '@mdi/js';
</script>

変数定義が不要になるので、かなりすっきりします。

それでも、ただアイコン置きたいだけみたいなときには、まあまあ面倒ではあるので、ファイルサイズ圧縮のためだけなら、下記のようなラッパーのモジュールを使うのもありです。

6
8
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
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?