Vue.js3でコードを書くとき、scriptタグ内にメソッド書きます。
同一ファイル(SFC)で定義した関数で呼び出すときは良いのですが、このメソッドを別のファイルから定義して呼び出したくなりましたが、refの扱いについてはまってしまったので、記事として残します。
Vue.js3を用いて、Composition APIで記述しています。
検証用に、以下のようなコードを書きました。
index.ts
<script setup lang="ts">
import { Ref, ref } from 'vue';
import { increment2 } from './increment';
const count = ref(0);
const increment1 = () => {
count.value++;
}
</script>
<template>
<main>
<p>カウント値</p>
<p>{{ count }}</p>
<button @click="increment1()">メソッド1</button>
<button @click="increment2(count)">メソッド2</button>
</main>
</template>
increment.ts
export const increment2 = (count: number) => {
count++;
}
この時、メソッド1ではカウントが増えますが、メソッド2ではカウントが増えません。increment2メソッドの引数には、refの値を渡しているのになぜ?
答えのヒントは、下記にありました。
<p>{{count}}</p>
templateタグ内では、refは自動的にアンラップされるのですね。画面に表示する意図ではなく、メソッドの引数として渡す場合でもです。
なので今回の場合、
@click="increment2(count)"
は、下記と等しくなっていました。
@click="increment2(count.value)"
increment2で加算されたcountの値は、リアクティブでないので、画面に反映されません。カウントにrefを渡すためには、scriptタグ内で値を渡すしかありません。
下記のように修正します。
import { increment2 } from "./increment.js";
const increment3 = () => {
increment2(count);
};
<button @click="increment3">メソッド3</button>
少々面倒ですが、外部ファイルに切り出したメソッドで、値を更新できるようになりました。