経緯
とある出来事がきっかけでVue3を改めて学び直したんだ。Amazonにあった「Vue 3 フロントエンド開発の教科書」を購入して勉強していた。誤解が無いように伝えておくが、この本は比較的新しい内容で、使われている技術もバージョンが新しいため、ある程度Web技術を学んでいれば楽しく読むことができる。Vue3の学び直しには打ってつけだった。知っていることも多かったので基本的にスラスラと読み進めていたが、多くの人がとある内容で壁にぶち当たることになる。
立ちはだかる壁
さてその壁は以下の記述である。内容をそのままコピーするとまずいかもしれないので、同じことを起こせるプログラムを代わりに用意した。
環境の要因をなくすために、公式サイトでRefの説明で使われていたPlaygroundを使っていこう。
App.vueを以下の記述にする。
<script setup lang="ts">
import { ref } from 'vue'
let value = "1";
const valueRef = ref(1);
function changeValue() {
value = "2";
valueRef.value = 2;
}
setInterval(changeValue, 1000);
</script>
<template>
<p>value: {{value}}</p>
<p>valueRef: {{valueRef}}</p>
</template>
さてこれを実行するとどうなるだろうか。以下がプログラムの変更が反映されてから1秒後の映像だ。
…
おいおいおいおいおいおいおいおいおいおいおいおいおい違うだろぉ??
valueは変更されない約束だろぉ?????
そもそもなぜRefを使うかというと、変数に何らかの変更があった際に、それに合わせてDOMを更新させるために使うのだ。だからRefを使っていない変数がscript内でどれだけ変更されようがUIで変化が起こるということが起こってはいけない(はず)。
実際以下のように、Refを使わない記述だけを残すと、表示が変わることはない。
<script setup lang="ts">
import { ref } from 'vue'
let value = "1";
function changeValue() {
value = "2";
}
setInterval(changeValue, 1000);
</script>
<template>
<p>value: {{value}}</p>
</template>
結論
結論としては、以下のリンク先の質問で解決されていた。
・https://teratail.com/questions/mcgaqdq8jvcw5c
要するにver. 3.2.45以降では、上記の挙動で正しいようだ。Refの値が更新されると、同じテンプレートに含まれている変数が全て再レンダリングされることで、Refを用いてない変数の表示まで変わってしまうということだ。
初学者にこの壁は手厳しい…