Nuxt 3 における script setup の基本的な使い方と FAQ
Vue.js 3.2 で導入された <script setup>
ですが Nuxt 3 でも利用可能です。
<script setup>
の基本的な使い方
Composition API ではあらたに setup()
が利用できるようになりました。
Component 作成時において props 等の解決が行われた時点で呼ばれます。
呼び出し側の Component (親 Component )で定義された情報のみアクセスでき Options API でいう this にアクセスすることはできません。
その setup()
の簡易な書き方(糖衣構文)が <script setup>
です。
(Vue.js 3.2 以降では <script setup>
による記述が推奨されています)
<script setup lang="ts">
const { data: posts } = await useFetch('/api/posts')
</script>
<template>
<div>
<h1>投稿一覧</h1>
<PostListItem
v-for="post in posts"
:key="post.id"
:post="post"
/>
</div>
</template>
上記の <script setup>
部分を、従来の Composition API で書くと次のようになります。
(script 内のみ)
<script lang="ts">
export default defineComponent({
async setup() {
const { data: posts } = await useFetch('/api/posts')
return {
posts,
}
},
})
</script>
export default defineComponent()
が不要となり async setup()
や最後の return
も使いません。
とてもシンプルに書けますね。
Compiler macro について
<script setup>
はコンパイル時に通常の構文に変換しています。
そのとき <script setup>
内でのみ使用可能な記述 Compiler macro も同様に処理します。
defineEmits
, defineExpose
, defineProps
, withDefaults
などは Vue.js が用意している Compiler macro です。
FAQ
そのほかのオプションを使いたい場合はどうしたらよいですか?
Vue.js では、次のように併用して書くことになります。
<script lang="ts">
export default defineComponent({
layout: false
})
</script>
<script setup lang="ts">
const { data: posts } = await useFetch('/api/posts')
</script>
Nuxt 3 の用意する Composable Function により、次のように書き換えることが可能です。
definePageMeta()
の使用例
<script setup lang="ts">
definePageMeta({
layout: 'custom',
});
</script>
これまでページコンポーネントに記述していた内容は基本的に definePageMeta()
を使用し記述可能です。
definePageMeta(meta: PageMeta) => void
interface PageMeta {
validate?: (route: RouteLocationNormalized) => boolean | Promise<boolean> | Partial<NuxtError> | Promise<Partial<NuxtError>>
redirect?: RouteRecordRedirectOption
alias?: string | string[]
pageTransition?: boolean | TransitionProps
layoutTransition?: boolean | TransitionProps
key?: false | string | ((route: RouteLocationNormalizedLoaded) => string)
keepalive?: boolean | KeepAliveProps
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
[key: string]: any
}
ref()
等はどのように import しますか?
Composition API (Reactivity API) の Nuxt 3 では使用頻度の高いものは import せずにグローバルに利用できるようになっています。
詳しくは自動生成される .nuxt/types/imports.d.ts
を見てください。
<script setup lang="ts">
const counter = ref(0)
const doubled = computed(() => counter.value * 2)
const increment = () => counter.value++
</script>
<template>
<div>
<p>{{ counter }}</p>
<p>{{ doubled }}</p>
<p><button @click="increment">カウントアップ</button></p>
</div>
</template>
Component 等はどのように import しますか?
Nuxt 3 はデフォルトで Component (components
内の .vue
ファイル) と Composable Function (composables
直下の .js
, .ts
ファイル内で export
された関数)を読み込みます。
これらの import は記述する必要がありません。
utils
フォルダ直下の.js
,.ts
ファイル内でexport
された関数も自動的に読み込まれるようになりました。
<script setup lang="ts">
const { counter } = useCount()
counter.value++
</script>
<template>
<div>
<TheHeader/>
<p>{{ counter }}</p>
</div>
</template>
export const useCount = () => {
const counter = ref(0)
return { counter }
}
<template>
<h1>カウント</h1>
</template>
Nuxt Context はどのように利用できますか?
useXxx()
のように利用できます。
<script setup lang="ts">
interface User {
name: string
age: number
}
const nuxtApp = useNuxtApp()
const { vueApp } = nuxtApp // 旧 app
const route = useRoute()
const router = useRouter()
const user = useState<User | null>('user', () => null)
const $config = useRuntimeConfig()
// 中略
</script>
グローバルに利用可能な関数の一覧はありますか?
npm run dev
すると作成される .nuxt
ディレクトリ内に .nuxt/types/imports.d.ts
などのファイルが生成されます。
Composition API の Reactivity API のほか defineXxx()
, useXxx()
, onXxx()
などが含まれていることが分かります。
Nuxt 3.0.0 本リリース時点では次のとおりです。
Nuxt App
useAsyncData
, useLazyAsyncData
, refreshNuxtData
, clearNuxtData
, defineNuxtComponent
, useNuxtApp
, defineNuxtPlugin
, useRuntimeConfig
, useState
, useFetch
, useLazyFetch
, useCookie
, useRequestHeaders
, useRequestEvent
, setResponseStatus
, setPageLayout
, useRouter
, useRoute
, defineNuxtRouteMiddleware
, navigateTo
, abortNavigation
, addRouteMiddleware
, showError
, clearError
, isNuxtError
, useError
, createError
, defineNuxtLink
, useAppConfig
, updateAppConfig
, defineAppConfig
, preloadComponents
, preloadRouteComponents
, prefetchComponents
, loadPayload
, preloadPayload
, isPrerendered
<script setup>
Compiler macro
withCtx
, withDirectives
, withKeys
, withMemo
, withModifiers
, withScopeId
,
withCtx
, withDirectives
, withKeys
, withMemo
, withModifiers
, withScopeId
,
defineEmits
, defineExpose
, defineProps
, withDefaults
, definePageMeta
Lifecycle
onActivated
, onBeforeMount
, onBeforeUnmount
, onBeforeUpdate
, onDeactivated
, onErrorCaptured
, onMounted
, onRenderTracked
, onRenderTriggered
, onServerPrefetch
, onUnmounted
, onUpdated
Reactivity
computed
, customRef
, isProxy
, isReactive
, isReadonly
, isRef
, markRaw
, proxyRefs
, reactive
, readonly
, ref
, shallowReactive
, shallowReadonly
, shallowRef
, toRaw
, toRef
, toRefs
, triggerRef
, unref
, watch
, watchEffect
, isShallow
Effect
effect
, effectScope
, getCurrentScope
, onScopeDispose
Component
defineComponent
, defineAsyncComponent
, resolveComponent
, getCurrentInstance
, h
, inject
, nextTick
, provide
, useAttrs
, useCssModule
, useCssVars
, useSlots
, useTransitionState
Nitro
cachedEventHandler
, cachedFunction
, defineCachedEventHandler
, defineCachedFunction
, defineNitroPlugin
, defineRenderHandler
, getRouteRules
, nitroPlugin
, useNitroApp
, useRuntimeConfig
, useStorage
h3
appendHeader
, appendHeaders
, appendResponseHeader
, appendResponseHeaders
, assertMethod
, callNodeListener
, createApp
, createAppEventHandler
, createError
, createEvent
, createRouter
, defaultContentType
, defineEventHandler
, defineLazyEventHandler
, defineNodeListener
, defineNodeMiddleware
, deleteCookie
, dynamicEventHandler
, eventHandler
, fromNodeMiddleware
, getCookie
, getHeader
, getHeaders
, getMethod
, getQuery
, getRequestHeader
, getRequestHeaders
, getResponseHeader
, getResponseHeaders
, getRouterParam
, getRouterParams
, handleCacheHeaders
, isError
, isEvent
, isEventHandler
, isMethod
, isStream
, lazyEventHandler
, parseCookies
, promisifyNodeListener
, proxyRequest
, readBody
, readRawBody
, send
, sendError
, sendProxy
, sendRedirect
, sendStream
, setCookie
, setHeader
, setHeaders
, setResponseHeader
, setResponseHeaders
, toEventHandler
, toNodeListener
, useBase
, writeEarlyHints
Vue Router
onBeforeRouteLeave
, onBeforeRouteUpdate
, useLink
その他
useHead
, useMeta
, isVue2
, isVue3
外部モジュールの import はどこで行いますか?
<script setup>
のなかで可能です。
次のように記述すれば、適切に使用できます。
<script setup lang="ts">
import { format } from 'date-fns'
const { postId } = useRoute().params
const { data: post } = await useFetch(`/api/post/${postId}`)
const published = computed(() => format(post.value.publishedAt, 'yyyy-MM-dd'))
</script>
インポートした関数は <template>
内で使用可能です。
<script setup lang="ts">
import { capitalize } from '@/helpers'
</script>
<template>
<div>{{ capitalize('hello') }}</div>
</template>
Reactivity API の型はどのように利用できますか?
'vue'
から呼び出します。
import type { Ref } from 'vue'
const inc = (counter: Ref<number>) => () => counter.value++
export const useCount = () => {
const counter = ref(0)
return {
counter: readonly(counter),
inc: inc(counter),
}
}
props, attr, slot はどのように使いますか?
Vue.js 3.x のドキュメントをご確認ください。
Discussion