Vue3 Composition APIのReactivity APIまとめ
vue3のComposition APIのrefとreactiveについて調べた際に、他のReactivity APIについても気になったので今回まとめました。
自分が理解できた箇所のみをまとめた浅い記事ですがご容赦ください。
- reactive
- ref
- computed
- readonly
- watchEffect
- watch
- unref
- toRef
- toRefs
- isRef
- isReactive
- isReadonly
- customRef
- markRaw
- shallowReactive
- shallowReadonly
- toRaw
- 終わりに
- 参考文献
reactive
オブジェクトをリアクティブなProxyオブジェクトにして返す関数です。
この際のリアクティブへの変換はディープコピーのようですが、返されるプロキシは元のオブジェクトと同一ではないようです。
const obj = reactive({count: 1}) console.log(obj.count) // 1 obj.count++ console.log(obj.count) // 2
ref
プリミティブな値をアクティブで可変なrefオブジェクトを返す関数です。
refオブジェクトにはvalueというプロパティがあり、これによってアクセスできるようです。
const count = ref(0) console.log(count.value) // 0 count.value++ console.log(count.value) // 1
computed
ゲッター関数を受け取り、ゲッターからの戻り値に対して不変のリアクティブなrefオブジェクトを返す関数です。
const count = ref(1) const plusOne = computed(() => count.value + 1) console.log(plusOne.value) // 2 count.value++ console.log(plusOne.value) // 3 plusOne.value++ // error
ゲッター関数とセッター関数を使えば、書き込み可能なrefオブジェクトを作成することもできます。
const count = ref(1) const plusOne = computed({ get: () => count.value + 100, set: val => { count.value = val - 1 } }) console.log(plusOne.value) // 101 plusOne.value = 100 console.log(count.value) // 99
readonly
オブジェクトまたはrefを受け取り、読み取り専用プロキシを返す関数です。
ネストされたプロパティも読み取り専用になるようです。
const original = reactive({ count: 0 }) const copy = readonly(original) original.count++ console.log(copy.count) // 1 // 読み取り専用だから書き換えられない copy.count++ // error
watchEffect
依存関係を事後的に追跡しながら関数をすぐに実行し、依存関係が変更されたときに関数を再実行します。
const count = ref(0) watchEffect(() => console.log(count.value)) // 0 setTimeout(() => { count.value++ // 1 }, 100)
watch
Vue2でのwatchとほぼ変わらないようです。
const state = reactive({ count: 0 }) watch( () => state.count, (count) => { sampleFunction(count) } )
複数を監視対象にすることもできるようです。
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { /* ... */ })
unref
引数がrefの場合は内部値を返し、それ以外の場合は引数自体を返す関数です。
const refSample = ref(100) const notRefSample = 10 unref(refSample) // 100 unref(notRefSample) // 10
toRef
リアクティブなオブジェクトのある特定のプロパティをrefオブジェクトに変換する関数です。
const state = reactive({ hoge: 1, fuga: 2 }) const sampleRef = toRef(state, 'hoge') sampleRef.value++ console.log(state.hoge) // 2 state.hoge++ console.log(sampleRef.value) // 3
toRefs
リアクティブなオブジェクトの全てのプロパティをrefオブジェクトに変換する関数です。
const state = reactive({ hoge: 1, fuga: 2 }) const sampleRefs = toRefs(state) state.hoge++ console.log(sampleRefs.hoge.value) // 2 sampleRefs.hoge.value++ console.log(state.hoge) // 3 sampleRefs.fuga.value++ console.log(state.fuga) // 3
isRef
値がrefオブジェクトであるかどうかを確認する関数です。
const sampleRef = ref(1) const sampleReactive = reactive({hoge: 1}) const sample = 1 console.log(isRef(sampleRef)) // true console.log(isRef(sampleReactive)) // false console.log(isRef(sample)) // false
isReactive
値がreactiveによって作成されたProxyオブジェクトであるかどうかを確認する関数です。
readonlyによってラップしたreactiveオブジェクトでもtrueを返すようです。
const sampleRef = ref('hoge'); const sampleReactive = reactive({ fuga: 'fuga' }); const sample = 'piyo' const sampleRefAsReadonly = readonly(sampleRef); isReactive(sampleRef) // false isReactive(sampleReactive) // true isReactive(sample) // false isReactive(sampleRefAsReadonly) // true
isReadonly
値がreadonlyかどうかを確認する関数です。
const sampleRef = ref("hoge"); const sampleReactive = reactive({ fuga: "fuga" }); const sampleReadonly = readonly(sampleReactive); isReadonly(sampleRef) // false isReadonly(sampleReactive) // false isReadonly(sampleReadonly) // true
customRef
更新のトリガーを明示的に制御し、カスタムしたrefオブジェクトを返すことができる関数らしいです。
const outputLogRef = (value: string) => { return customRef((track, trigger) => ({ get() { console.log(value) track() return value }, set(newValue: string) { console.log(newValue) value = newValue trigger() } })) } const hoge = outputLogRef("") hoge.value = "hoge" // hogeが出力される hoge.value = "fuga" // fugaが出力される const fuga = hoge.value // fugaが出力される
markRaw
オブジェクトをマークして、reactiveなProxyオブジェクトに変換しないようにする関数らしいです。
const hoge = markRaw({}) console.log(isReactive(reactive(hoge))) // false
shallowReactive
ネストされたプロパティ以外をリアクティブにして返す関数です。
const state = shallowReactive({ hoge: 1, fuga: { piyo: 2 } }) // これはリアクティブ isReactive(state.hoge) // ネストされたプロパティはリアクティブじゃない isReactive(state.fuga) // false
shallowReadonly
ネストされたプロパティ以外をreadonlyにして返す関数です。
const state = shallowReadonly({ hoge: 1, fuga: { piyo: 2 } }) // これはreadonly isReadonly(state.hoge) // ネストされたプロパティはreadonlyじゃない isReadonly(state.fuga) // false
toRaw
reactiveまたはreadonlyオブジェクトの元のオブジェクトを返す関数です。
const sample = {} const reactiveSample = reactive(sample) console.log(toRaw(reactiveSample) === sample) // true
終わりに
Compotion APIのReactivity APIをまとめてみました。
Vue2のComposition APIのプラグインではまだ対応しておらず、全く見たことないものや
いつ使うのか全く分からないものもありましたが、適宜用途に合わせて使っていきたいと思います。