7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめての Nuxt3 × TypeScript

Last updated at Posted at 2023-08-02

Nuxt3を学ぶに当たって参考になったサイト

Data

関数ref()を使用し、変数に代入します。
こちらの変数の値を使用する時はcount.valueのように.valueが必要です。※代入時も同様
<template>内から参照する場合は.valueが必要ありません。

オブジェクトをリアクティブに管理したい時などは、reavtive()を使用して定義します。
こちらの記事を見た感じだと、基本的にref()のみで良さそうです。

<script setup lang="ts">
const count = ref(0);

// オブジェクトの場合
const user = reactive({
  name: "佐藤",
  age: 21,
});

// 出力結果:0
console.log(count.value);

// 出力結果:21
console.log(user.age);

count.value = 2;
user.name = "山田";
</script>

Props

コンポーネントのpropsの定義は以下のように行います。
以下のコードのようにprops変数に入れなくても使用できますが、<script setup>内から参照出来ないため、統一も含め変数に入れることが好ましいと思います。

また、<template>内ではprops.classのようにしなくてもclassと記述するだけでpropsの値を使用できます。

<script lang="ts" setup>
interface Props {
  message: string | number;
  class?: string;
}

// デフォルトを定義
const props = withDefaults(defineProps<Props>(), { class: "msg-class" });

// デフォルトがない場合はこのように定義する
// const props = defineProps<Props>();
</script>

<template>
  <!-- props.を使用しなくても使える例 -->
  <p :class="class">
    {{ props.message }}
  </p>
</template>

Emit

コンポーネントからのemitは以下のようにすることで定義できます。
type Emitsは型定義だけでなく見ただけで、そのコンポーネントが何をemitするのか分かりやすくしてくれます。

<script lang="ts" setup>
type Emits = {
  // 1つめにイベント名, 2つ目にemitする値の型
  (event: "change", value: string): void;
};

const emits = defineEmits<Emits>();
const onChange = (event: any): void => {
  emits("change", event.target.value);
};
</script>

<template>
  <input :type="text" @change="onChange" />
</template>

Mounted

mounted動きはNuxt2の時と同じです。
書き方は以下になります。

<script setup lang="ts">
const count = ref(0)
// 出力結果:0
console.log(count.value)

onMounted(() => {
  count.value = 1
  // 出力結果:1
  console.log(count.value)
})

// 出力結果:0
console.log(count.value)
</script>

Computed

computedの動きも基本的にNuxt2の時と同じです。
書き方は以下になります。

<script setup lang="ts">
const count = ref(0);

const buttonStyle = computed((): { width: string } => {
  // ここではbuttonタグのstyleを定義
  return {
    width: `${count.value * 10}px`,
  };
});
</script>

<template>
  <button :style="buttonStyle">sample</button>
</template>

テスト時に注意すること(Vitest)

Nuxt3でcomputedは自動でインポートされていますが、Vitestはそれを認識することができず、エラーになります。
そこで以下のライブラリを導入し、vitest.config.tsに書き加えます。

$ yarn add unplugin-auto-import -D

vitest.config.ts

/// <reference types="vitest" />
import { defineConfig } from "vite";
import Vue from "@vitejs/plugin-vue";
import path from "path";
import AutoImport from "unplugin-auto-import/vite"; // 追加
export default defineConfig({
  plugins: [
    Vue(),
    AutoImport({  // 追加
      imports: ["vue"],
    }),
  ],
  test: {
    globals: true,
    environment: "jsdom",
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});

Watch

基本的にwatch関数は以下のように使用します。

<script lang="ts" setup>
const count = ref(0);

// 複数同時に監視したい場合、配列にする[count, ...]
watch(count, (count, prevCount) => {
  console.log(`watch: ${prevCount} -> ${count}`);
});

// method
function countUp() {
  count.value++;
}
</script>

<template>
  <div>
    <p>count: {{ data.count }}</p>
    <button @click="countUp">COUNT UP</button>
  </div>
</template>

オブジェクトをwatchしたい場合は、記述方法が異なります。

watch(() => props.監視したいプロパティ名, () => {
  // 処理
})

deepなどのオプションはこのように記述します。

watch(() => props, () => {
  // 処理
},
{ deep: true }
)
7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?