Vue3のscript setupをさわってみた

script setupとは

script setupはVueの3.2で正式リリースされたComposition API形式のシンタックスシュガー(糖衣構文)です。


公式サイトでは以下のメリットが説明されています。

  • ボイラープレートを減らし、より簡潔なコードになる
  • プロパティやEmitに型を定義可能(TypeScript利用時)
  • ランタイムパフォーマンスの向上
  • IDE(開発環境)での型推論のパフォーマンスの向上

早速色々と触ってみましたので、紹介していきたいと思います。

公式ドキュメントはこちら

またComposition APIについて記事を書きましたので、よろしければこちらもご覧ください。

基本構文

scriptタグにsetup属性を追加します。

<script setup>
console.log("こんにちは!")
</script>

従来までのdefineComponentのsetupの中身をトップレベルに記述することができます。

変数・関数の公開

scriptタグ内の直下に定義された変数・関数はテンプレートで利用できます。
また、同様にインポートした変数・関数も利用可能です。

<script setup lang="ts">
import {hoge} from "@/utils/some-utils"
// 変数
const name = "犬わんわん"

// 関数
const sayHello = () => {
    console.log("こんにちは!")
}
</script>
<template>
    <div>名前: {{name}}</div>
    <button @click="sayHello">あいさつ</button>
    <button @click="hoge">ほげ</button>
</template>

リアクティブ

reactive, ref, computedなどのリアクティブオブジェクトについても基本的な使い方は同じです。

<script setup lang="ts">
import {ref, reactive, computed} from "vue"
// ref
const count = ref(0)

// reactive
const state = reactive({
    name: "inu-wanwan",
    age: 5,
})

// computed
const uName = computed(() => state.toUpperCase())

</script>
<template>
    <div>名前: {{state.name}} | {{uName}}</div>
    <div>年齢: {{state.age}}</div>
    <div>カウント: {{count}}</div>
    <button @click="count++">カウントアップ</button>
</template>

1点注意ですが、従来までのdefineComponentを利用した表記方法ではreturn時にtoRefsとスプレッド演算子を利用してreactiveのプロパティを展開することができたのですが、script setupでは明示的に展開するプロパティを指定する必要があります。

defineComponent

<script lang="ts">
import {defineComponent, reactive, toRefs} from "vue"

export default defineComponent({
    setup() {
        const state = reactive({
            name: "inu-wanwan",
            age: 5,
        })

        return {
            ...toRefs(state), // stateのプロパティをrefに変換し公開
        }
    }
})
</script>

script setup

<script setup lang="ts">
import {reactive, toRefs} from "vue"

const state = reactive({
    name: "inu-wanwan",
    age: 5,
})

const {name, age} = toRefs(state)  // 明示的に公開するプロパティを指定する必要がある

</script>

他コンポーネントの利用

defineComponentでは他のコンポーネントを利用するにはcomponentsで利用するコンポーネントを指定する必要がありましたが、script setup表記ではコンポーネントをインポートするだけで利用可能です。

defineComponent

<script lang="ts">
import {defineComponent} from "vue"
import HogeComponent from "@/components/HogeComponent.vue"

export default defineComponent({
    components: {
        HogeComponent,
    },
})
</script>
<template>
    <hoge-component />
</template>

script setup

<script setup lang="ts">
import HogeComponent from "@/components/HogeComponent.vue"
</script>
<template>
    <hoge-component />
</template>

楽ちんですね!

プロパティ・Emitの定義

プロパティ・Emitを定義するにはそれぞれdefineProps、defineEmitsを使います。
の記述方法はdefineComponentの場合と同様です。

<script setup lang="ts">
import {defineProps, defineEmits} from "vue"
// プロパティの定義
const props = defineProps({
    name: {type: String, required: true, default: ""},
    age: Number,
})

// Emitの定義
const emit = defineEmits(["open", "close"])
</script>

また、TypeScript環境では厳密な型定義が可能です。個人的にはこの機能を一番待ち望んでいました!

<script setup lang="ts">
import {defineProps} from "vue"

// プロパティの定義
const props = defineProps<{
    name: string
    age?: number
}>()

// Emitの定義
const emit = defineEmits<{
    (e: "open", name: string): void
    (e: "close", name: string): void
}>()
</script>

型定義を使用した場合、デフォルト値の定義はwithDefaultsを使用します。

<script setup lang="ts">
import {defineProps, withDefaults} from "vue"

interface Props {
    name: string
    age?: number
}

const props = withDefaults(defineProps<Props>(), {
    name: "",
    age: 0,
})
</script>

IDEのサポート

私は普段JetBrainsのintelliJ IDEAを使っているのですが、2021年8月23日時点でEAPバージョンでscript setupでコードを書いた場合でもしっかり補完が効いています。
恐るべしJetbrains!!

まとめ

Vueはバージョンが3に上がり、より洗練されて来ている印象です。
今後も新しい機能を追いかけて行きたいと思います。

最後まで読んでくださりありがとうございました。

タイトルとURLをコピーしました