まずこちらをご覧ください。
num
にはリアクティブな0が入ってて、msg
にはnum
の値の型をcomputed
で出力します。
num
が代入された直後なので上に表示された型名はnumber
ですが、下のinput要素内の値を変えてみてください。
なんと変えた瞬間に型名がstring
になったではないですか!!
そう、input要素のvalueプロパティはstring
になるのです!知ってましたか?
自分は知りませんでした。しかし今日発見しました。
自分が今まで気づかなかった理由
皆さんご存じだと思いますが、JavaScriptは動的型付け言語です。
開発者ツールのコンソールなどで以下を入力してエンターしてみてください。
"2" * 2
なんと4になるではないですか!!
しかし本当は文字列なのかもしれない。という希望をもってtypeof
してみましょう。
typeof ("2" * 2)
なんと普通の数字ではないですか!!
そう、こういう文字列を数字と解釈したりするため、気づかないことがあるのです!!
ちなみに確認した範囲では-
、/
、**
、などの演算子、
===
以外の比較演算子や、Math
オブジェクト系も勝手にnumber
に解釈するようです
自分が今日気づいた理由
+
したら気づきました。
なんと+
するときはnumber
をstring
に解釈するではないですか!!
は?となりますが、このコードをみればその理由がわかるでしょう。
let pi = 3.14;
console.log("円周率は" + pi + "だよ!");
2行目の二つの文字列をnumber
に変換しようものなら両方がNaN
になってNaN
が出力されてしまいます。
対処法
1.演算時にparseIntする(Vueじゃなくてもいい)
import {ref} from "vue"
const num = ref(0)
watch(num,()=>{
console.log(parseInt(num.value) + 1)
})
演算するたびにこの関数が必要になります。
2.parseIntするcomputedを参照する
import {ref,computed} from "vue"
const input = ref(0)
const inputnum = computed(()=>parseInt(input.value))
watch(inputnum,()=>{
consle.log(inputnum.value + 1)
})
演算するたびに呼び出さなくていいし、Vueの要素プロパティに直接使えます。
3.computedのセッターとゲッターを使う
import {computed} from "vue"
let realNum = 0
const num = computed({
get() {
return realNum
},
set(newval) {
realNum = parseInt(newval)
}
})
値が入った瞬間に数値に変換します。
computed
を代入した変数でリアクティブに使えるし、
realNum
では関数内などで.value
無しで読み取りできます。
これが一番便利だと思います。
まとめ
これはVueに限らないので知っておいて損はないです。
数字のinput
はparseInt
しよう!