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 }
)