
ブログをNext.js14(App Router)でリファクタリングしました
Vue3.2で<script setup>構文が導入され、Composition APIの記述が簡単になりました。<script setup>構文は記述が簡単になるだけでなく、他にも多くのメリットが存在します。この記事では<script setup>構文の説明から、propsやemitなどの特有の記述方法、メリットなどを説明します。
目次
<script setup>構文は、従来のComposition APIのシンタックスシュガー(中身は同じで別の書き方)です。
Composition APIをご存じない方はこちらの記事を参照下さい。
<script setup>構文ですが、使うために必要なのはscriptタグ内ににsetupと記述するだけです。
まずは従来の記述方法と比較することで、具体的な記述方法を見ていきます。
<script lang="ts" setup>
import { computed, ref } from 'vue'
//変数
const hoge = ref("hoge")
const num = ref<number>()
//関数
const onClick = () => console.log("clicked!")
//computed
const twice = computed(() => num.value)
</script>
同じ内容のコードを従来通りに書くと次のようになります。
<script lang="ts">
import { defineComponent, ref, computed } from "vue";
export default defineComponent({
setup() {
//変数
const hoge = ref("hoge")
const num = ref<number>()
//関数
const onClick = () => console.log("clicked!")
//computed
const twice = computed(() => num.value)
return {
hoge, num, onClick, twice
}
}
})
</script>
見ての通り、最初に記載した<script setup>構文では圧倒的に記述が楽になりました。
また、全てトップレベルに記述できるのでコードの見通しも良いです。
具体的に言うと、次の3つの記述が不要になります。
トップレベルに書いた変数や関数はがそのままtemplateで使えるのです。
記述が楽になりコードの見通しが良くなる、以外にも多くのメリットが存在します。
いくつか紹介します。
従来のComposition APIでPropsとEmitは、setup()と同じ階層に併記していました。
<script setup>構文では、definePropsやdefineEmitsを用いて、トップレベルに記述します。
<script setup lang="ts">
const props = defineProps({
num: {
type: Number,
required: true
},
str: {
type: String,
default: "hoge"
}
})
const emits = defineEmits(
['change']
)
</script>
typeやrequired、defaultの書き方は普通のsetup文の時と変わりません。
TypeScriptのジェネリックを使えば、更に簡単に記述できます。
<script setup lang="ts">
const props = defineProps<{
num: number,
str?: string //?なのでrequired: falseと同じ
}>()
const emits = defineEmits<{
(e: 'change', id: number): void
}>()
</script>
以下、このコードについて解説します。
コード例に載せたとおり、propsの型はTypeScriptの記述で指定します。
「num: number」はnumber型で必須(required: true)のpropsを表し、
「str?: string」はstring型で任意(required: false)のpropsにできます。
このように?の有無でrequiredの指定ができます。
ただし、この記述方法ではpropsのデフォルト値が表現できません。
デフォルト値が必要な場合はwithDefaults関数を利用します。
const props = withDefaults(defineProps<{
num?: number,
str?: string
}>(), {
num: 3,
str: "hoge"
})
また、scriptブロック内でpropsは利用せずにtemplateブロック内でのみ利用する場合、const propsに代入せずに次のような宣言をするだけで構いません。
defineProps<{ msg: string }>()
ジェネリックの<>内で必要な数のemitを定義していきます。
基本的な書き方は次のとおりです。
const emits = defineEmits<{
(e: "Emitの名前", 渡したい引数: 型): void
(e: "Emitの名前2", 渡したい引数: 型): void
}>()
具体的な使用例を載せます。
<script setup lang="ts">
const emits = defineEmits<{
(e: "hoge", num: number): void
(e: "fuga"): void
}>()
const onclick = () => {
emits("hoge", 3) //3を引数にhogeを発火
emits("fuga") //引数無しでfugaを発火
}
</script>
templateで使うコンポーネントは、script setupブロック内でimportするだけで、template側で使用可能になります。
<script setup lang="ts">
import Child from './Child.vue';
</script>
<template>
<Child />
</template>
親がテンプレート参照を用いて子トップレベルの変数等にアクセスするには、defineExposeを使う必要があります。
const num = ref<number>()
defineExpose({
num
})
これで、このコンポーネントを利用する親コンポーネントはテンプレート参照を用いてnumにアクセスできます。
<script setup>構文ではexportの記述ができません。
従来の<script>だけの構文も記述してexportする必要があります。
<script lang="ts">
export const hoge = "fuga" //OK
</script>
<script setup lang="ts">
// export const fuga = "fuga" //エラー
</script>
<script setup>構文について、一通りの使い方とメリットを紹介しました。非常に多くのメリットが存在し、記述が簡単になり開発効率も上がるので積極的に利用すべきです。
関連記事
最新の記事
カテゴリー一覧
アーカイブ