Nuxt3勉強ログ
// プロジェクト作成
npx nuxi@latest init <プロジェクト名>
// 依存関係をインストール
yarn install
// 実行
yarn dev -o
プロジェクト直下で tree -I 'node_modules' -f
.
├── ./README.md
├── ./app.vue
├── ./nuxt.config.ts
├── ./package.json
├── ./public
│ └── ./public/favicon.ico
├── ./server
│ └── ./server/tsconfig.json
├── ./tsconfig.json
└── ./yarn.lock
3 directories, 8 files
app.vue
<template>
<div>
<NuxtPage />
</div>
</template>
pages/index.vue
<template>
<h1> Hello World </h1>
</template>
NuxtPage
はpage
のindex.vue
を呼び出す
nuxt.config.ts
hotreload
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
vite: {
server: {
watch: {
usePolling: true,
},
},
},
})
slot
コンポーネントの引数として渡された内容をそのまま表示する感じ
<template>
<div>
<slot />
</div>
</template>
components
ディレクトリ構造
components/
├── BaseTitle.vue
└── child
└── ttile.vue
index.vue
<template>
<h1> Hello World </h1>
<BaseTitle>
<h2> Hello World </h2>
<h3> Hello World </h3>
<h4> Hello World </h4>
</BaseTitle>
<ChildTtile>
<h2> Hello World </h2>
<h3> Hello World </h3>
<h4> Hello World </h4>
</ChildTtile>
</template>
components
直下だとファイル名 / サブディレクトリ下だと<サブディレクトリ名><ファイル名>
のアッパーキャメルケースで宣言するとUIコンポーネントとして呼び出せる
<template>
<NuxtLink to="/about">
About page
</NuxtLink>
<!-- <a href="/about">...</a> (+Vue Router & prefetching) -->
</template>
遷移関連のデフォルトコンポーネント。to=<遷移先>を指定する形
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<template>
<div>
<p>Some default layout content shared across all pages</p>
<slot />
</div>
</template>
<NuxtLayout>
でラップすることにより、layouts
ディレクトリのレイアウト表示用のvueファイルを適用できる。
Routing
useRoute()で現在のルート(パス)を取得する。
基本的に[xxx].vue
のxxxで具体的にパスからxxx
の情報を取得するための変数名的な感じで取得する
about/
├── [name].vue
└── index.vue
<script setup lang="ts">
const route = useRoute()
</script>
<template>
<div> This is the about page {{ route.params.name }}</div>
</template>
<style lang="less" scoped></style>
URL: http://localhost:3000/about/ady
SEO対応
SEOに重要なようそをuseSeoMeta 一発で設定可能
composables
アプリケーション内で自動でimportされるディレクトリ。
基本ロジックをカプセル化し、再利用しまくるコードを書く感じかな?
export default
JavaScriptのモジュールシステムにおける一部で、特定のモジュールから一つの値(関数、オブジェクト、クラス、プリミティブなど)をエクスポートするために使用されます。
export defaultが指定された値は、他のファイルからimport文を使ってインポートできます。
export default function useTodo() {
const todoList = ref([]);
function addTodo(payload) {
todoList.value = [...todoList.value, payload];
}
return {
todoList,
addTodo
}
}
<template>
<div>
<button @click="addToList">Add Todo</button>
</div>
</template>
<script setup lang="ts">
const { todoList, addTodo } = useTodo()
function addToList() {
addTodo({
id: todoList.value.length + 1,
text: 'New Todo',
})
console.log('added todoList', todoList.value)
}
</script>
<style lang="scss" scoped></style>
ref()
state管理。なんでも管理できちゃう優れもの。
(範囲が広過ぎて、大量に生やすとめんどくさそう、、、)
一応、テンプレート参照と日本語で言うらしい。
内部実装
export interface Ref<T = any> {
value: T;
/**
* Type differentiator only.
* We need this to be in public d.ts but don't want it to show up in IDE
* autocomplete, so we use a private Symbol instead.
*/
[RefSymbol]: true;
}
onMounted
コンポーネントがマウントされた後に呼び出されるコールバックを登録します。
httpリクエスト
Fetch APIというものが一応ある。だが、基本的にaxiosでいいと思う。
Fetchは必要最小限&サポートしていないブラウザもあるらしく、モダンな形で開発するのが丸そう
Nuxt3では、useFetchを使うのがモダンらしい
なんか調べているとNuxt3では基本useFetchを使うらしい。非同期処理の状態をキャッチできるから、投げて結果を取得するのみのaxosよりいいかも?
useFetchでGoogle Books APIを叩く
マウントするタイミングで(useFetchの)refresh value
を呼び出すことにより、useFetch
が発火する。
(ちなみにonMounted
の部分をコメントアウトしても描画される。おそらくbookを参照するタイミングで自動で呼び出されるのかな?)
<template>
<div>
<h1> {{ book?.items[0]?.volumeInfo?.title }} </h1>
<p> {{ book?.items[0]?.volumeInfo?.description }} </p>
<img :src="book?.items[0]?.volumeInfo?.imageLinks?.thumbnail" />
</div>
</template>
<script setup lang="ts">
onMounted(() => {
console.log('mounted')
refresh()
})
const { data: book, error, refresh, pending } = useFetch(
'volumes?q=nuxt',
{
method: 'GET',
baseURL: 'https://www.googleapis.com/books/v1/',
},
)
</script>
<style lang="scss" scoped></style>
個人的にはaxosの書き方の方が好み。やっぱりmethodをベタ書きだとタイポの恐れあるからな、、、わいはGitHub Copilotのおかげで補完されるけど、エディタで補完されなければ地味に辛いし、コード読む時にmethod property
を確認するのが慣れが必要かな。
サーバーとして処理をまとめ、useFetch等でデータを取得する
middleware
ルート(ページ)移動が完了する前に実行するプログラムを定義。
基本的に2種類あり、
-
xxx.global.ts
: ルート移動時、絶対呼び出される(以後「global」と呼称) - xxx.ts: 移動先に定義していないと呼び出されない(以後、「無印」と呼称)
の2種類がある。
また優先度はglobal
> 無印
となっている。
基本的な書き方
middleware内でコードを実行する方法
export default defineNuxtRouteMiddleware((to, from) => {
// to: 遷移元の情報
// from: 遷移後の情報
})
を定義。
無印のためにpage内で宣言する方法
<script setup lang="ts">
definePageMeta({
middleware: [
function (to, from) {
// to: 遷移元の情報
// from: 遷移後の情報
},
'<ファイル名>', // 「current.ts」なら、current
],
});
</script>
State管理
これで基礎のきを憶える