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
そのほかのオプションを使いたい場合はどうしたらよいですか?
次のように併用して書くことになります。
<script lang="ts">
export default defineComponent({
layout: false
})
</script>
<script setup lang="ts">
const { data: posts } = await useFetch('/api/posts')
</script>
ref()
等はどのように import しますか?
Composition API (Reactivity API) の Nuxt 3 では使用頻度の高いものは import せずにグローバルに利用できるようになっています。
詳しくは .nuxt/types/auto-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
ファイルの useXxx()
)を読み込みます。
これらの import は記述する必要がありません。
<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/auto-imports.d.ts
などのファイルが生成されます。
Composition API の Reactivity API のほか defineXxx()
, useXxx()
, onXxx()
などが含まれていることが分かります。
rc2リリース時点では次のとおりです。
Nuxt, Vue
useAsyncData
, useLazyAsyncData
, refreshNuxtData
, defineNuxtComponent
, useNuxtApp
, defineNuxtPlugin
, useRuntimeConfig
, useState
, useFetch
, useLazyFetch
, useCookie
, useRequestHeaders
, useRequestEvent
, useRouter
, useRoute
, useActiveRoute
, defineNuxtRouteMiddleware
, navigateTo
, abortNavigation
, addRouteMiddleware
, throwError
, clearError
, useError
, defineNuxtLink
, useSlots
, useAttrs
<script setup>
Compiler macro
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
defineCachedFunction
, defineCachedEventHandler
, useRuntimeConfig
, useStorage
, useNitroApp
, defineNitroPlugin
, nitroPlugin
, defineEventHandler
, defineLazyEventHandler
h3
defineEventHandler
, defineLazyEventHandler
, eventHandler
, lazyEventHandler
, dynamicEventHandler
, appendHeader
, assertMethod
, createError
, handleCacheHeaders
, isMethod
, sendRedirect
, useCookies
, useCookie
, deleteCookie
, setCookie
, useBody
, useMethod
, useQuery
, useRawBody
その他
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 の型はどのように利用できますか?
現時点(rc2 リリース時点)では '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