Vue Composition APIのリファレンスを見たらリアクティブ周りのAPIが大量に追加されていたのでまとめてみました。
この記事は以下バージョン時点の情報です。
-
vuejs/composition-api:
v1.0.0-beta.1
-
vuejs/vue-next:
v3.0.0-beta.17
Vue Composition APIのAPI Reference に掲載されているいくつかのAPIは、まだVue2系で使えるComposition APIのプラグイン(vuejs/composition-api)でサポートされていません。
そのAPIについては マークを末尾につけています。サポート対応状況についてはこちらの記載をもとにしています。
reactive
引数に渡したオブジェクトのリアクティブなプロキシを返します。
Vue2系のVue.observable()と同等の機能です。ネストされたオブジェクトもリアクティブな値として保持されます。
const obj = reactive({
name: "Foo",
address: {
city: "Bar"
}
})
obj.address.city = "Huga"
console.log(obj.address.city) // Huga
型定義
function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;
ref
プリミティブな値をrefオブジェクトに変換して返します。refオブジェクトはvalueプロパティでリアクティブな値にアクセスできます。
refの値としてオブジェクトが代入されている場合は、reactiveメソッドによってオブジェクトを深くリアクティブにします。
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
型定義
interface Ref<T = any> {
[RefSymbol]: true;
value: T;
}
function ref<T extends object>(value: T): T extends Ref ? T : Ref<UnwrapRef<T>>;
function ref<T>(value: T): Ref<UnwrapRef<T>>;
function ref<T = any>(): Ref<T | undefined>;
computed
コールバック関数を受け取り、戻り値をリアクティブでReadonlyなrefオブジェクトとして返します。
refオブジェクトの値は、コールバック関数内にあるリアクティブな値の変化に応じて再計算されます。
(getterとsetterを持つオブジェクトを渡して書き込み可能な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 = 4 // Error
型定義
// read-only
function computed<T>(getter: () => T): Readonly<Ref<Readonly<T>>>
// writable
function computed<T>(options: {
get: () => T
set: (value: T) => void
}): Ref<T>
readonly ️
オブジェクト(ref or reactive or プレーン)を受け取り、読み取り専用のリアクティブなプロキシを返します。
軽量な独自storeの周りの実装で使えそうです。
※ 2020/07/03現在、vue-composition-apiプラグインではサポートされてません。
const original = reactive({ count: 0 })
const copy = readonly(original)
console.log(copy.count) // 0
original.count++
console.log(copy.count) // 1
console.log(isReactive(copy)) // true
copy.count++ // Error
型定義
function readonly<T extends object>(target: T): Readonly<UnwrapNestedRefs<T>>;
customRef
依存関係の追跡と更新のトリガーを明示的に制御するカスタマイズされたrefオブジェクトを返します。
限定された用途でリアクティブな値を使いたい時に良さそうです。
※ 2020/07/03現在、vue-composition-apiプラグインではサポートされてません。
// 代入と参照時に必ずconsole.log()を実行するref
const useLoggerRef = (value: string) => {
return customRef((track, trigger) => ({
get() {
console.log(value)
track()
return value
},
set(newValue: string) {
console.log(newValue)
value = newValue
trigger()
}
}))
}
const foo = useLoggerRef("")
foo.value = "Hoge" // console.log("Hoge")が実行される
foo.value = "Bar" // console.log("Bar")が実行される
const bar = foo.value // console.log("Bar")が実行される
型定義
function customRef<T>(factory: CustomRefFactory<T>): Ref<T>
type CustomRefFactory<T> = (
track: () => void,
trigger: () => void
) => {
get: () => T
set: (value: T) => void
}
markRaw
リアクティブ化されない(プロキシされない)オブジェクトを返します。
適宜markRawを使いプロキシ変換をスキップすることで、不変のデータソースを持つ大規模なリストのレンダリングなどでパフォーマンスを向上させることができます。
const foo = markRaw({
baz: "baz"
})
const bar = reactive(foo)
isReactive(bar) // false reactive関数を実行してもリアクティブにならない
型定義
function markRaw<T extends object>(value: T): T
shallowReactive
浅いリアクティブなオブジェクトを返します。ネストされたオブジェクトはリアクティブ化されません。
const state = shallowReactive({
foo: 1,
nested: {
bar: 2
}
})
isReactive(state) // true
isReactive(state.nested) // false
型定義
function shallowReactive<T extends object>(target: T): T;
shallowRef
浅いリアクティブなrefオブジェクトを返します。ネストされたオブジェクトはリアクティブ化されません。
const foo = ref({})
const bar = shallowRef({})
isReactive(foo.value) // true
isReactive(bar.value) // false
型定義
function shallowRef<T>(value: T): T extends Ref ? T : Ref<T>;
shallowReadonly
浅いreadonlyなオブジェクトを返します。ネストされたオブジェクトはreadonlyになりません。
※ 2020/07/03現在、vue-composition-apiプラグインではサポートされてません。
const state = shallowReadonly({
foo: 1,
nested: {
bar: 2
}
})
// mutating state's own properties will fail
state.foo++
// ...but works on nested objects
isReadonly(state.nested) // false
state.nested.bar++ // works
型定義
function shallowReadonly<T extends object>(target: T): Readonly<{
[K in keyof T]: UnwrapNestedRefs<T[K]>;
}>;
toRaw
プロキシされたリアクティブなオブジェクトの生データを返します。
const foo = {}
const reactiveFoo = reactive(foo)
isReactive(toRaw(reactiveFoo)) // false
toRaw(reactiveFoo) === foo // true
型定義
function toRaw<T>(observed: T): T;
unref
引数がrefの場合はref.value
の値を、それ以外だったら引数自体を返します。
val = isRef(val) ? val.value : val
の糖衣構文です。
const foo = ref(1)
const bar = 1
unref(foo) // 1
unref(bar) // 1
型定義
function unref<T>(ref: T): T extends Ref<infer V> ? V : T;
toRef
reactiveなオブジェクトの指定のプロパティをrefオブジェクトに変換して返します。
propsの値をリアクティブを切らず、setup関数外のコンポーザブルな関数に渡すときなどに使えます。
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
isRef(fooRef) // true
型定義
function toRef<T extends object, K extends keyof T>(object: T, key: K): Ref<T[K]>;
toRefs
reactiveなオブジェクトの全てのプロパティをrefオブジェクトに変換したオブジェクトを返します。
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
isRef(stateAsRefs.foo) // true
isRef(stateAsRefs.bar) // true
型定義
type ToRefs<T = any> = {
[K in keyof T]: Ref<T[K]>;
};
function toRefs<T extends object>(object: T): ToRefs<T>;
isRef
refオブジェクトでラップされているかどうかを判定します。
const foo = ref("foo");
const bar = reactive({
bar: "bar"
});
isRef(foo) // true
isRef(bar) // false
型定義
isRef<T>(value: any): value is Ref<T>;
isReactive
reactiveかどうか判定します。reactiveで作られたオブジェクトをラップしたreadonlyなオブジェクトの場合にもtrueを返します。
const foo = ref("foo");
const bar = reactive({
bar: "bar"
});
const baz = readonly(bar);
const hoge = readonly(foo)
isReactive(foo) // false
isReactive(bar) // true
isReactive(baz) // true
isReactive(hoge) // false
型定義
function isReactive(value: unknown): boolean;
isReadonly
オブジェクトがreadonlyかどうか判定します。
※ 2020/07/03現在、vue-composition-apiプラグインではサポートされてません。
const foo = ref("foo");
const bar = reactive({
bar: "bar"
});
const baz = readonly(bar);
isReadonly(foo) // false
isReadonly(bar) // false
isReadonly(baz) // true
型定義
function isReadonly(value: unknown): boolean;
isProxy
オブジェクトがProxyか判定します。reactiveかreadonlyで作成したオブジェクトが該当します。
※ 2020/07/03現在、vue-composition-apiプラグインではサポートされてません。
const foo = ref("foo");
const bar = reactive({
bar: "bar"
});
const baz = readonly(bar);
isProxy(foo) // false
isProxy(bar) // true
isProxy(baz) // true
型定義
function isProxy(value: unknown): boolean;
終わりに
以上「Vue Composition API v1-beta で使えるリアクティブ関連のAPI一覧」でした。思った以上にAPIが多いですね。
業務ではref, reactive, toRef, toRefs, isRefくらいしか使ってなかったです。
今後はどんどん活用していきたいです。