vue3 常用的API
reactive
返回对象的响应式副本
const obj = reactive({ count: 0 })
响应式转换是“深层”的——它影响所有嵌套 property。在基于 ES2015 Proxy (opens new window)的实现中,返回的 proxy 是不等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。
类型声明:
function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
readonly
获取一个对象 (响应式或纯对象) 或 ref 并返回原始 proxy 的只读 proxy。只读 proxy 是深层的:访问的任何嵌套 property 也是只读的。
const original = reactive({ count: 0 }) const copy = readonly(original) watchEffect(() => { // 适用于响应性追踪 console.log(copy.count) }) // 变更original 会触发侦听器依赖副本 original.count++ // 变更副本将失败并导致警告 copy.count++ // 警告!
isProxy
检查对象是否是由 reactive
或 readonly
创建的 proxy。
isReactive
检查对象是否是 reactive
创建的响应式 proxy。
import { reactive, isReactive } from 'vue' export default { setup() { const state = reactive({ name: 'John' }) console.log(isReactive(state)) // -> true } }
如果 proxy 是 readonly
创建的,但还包装了由 reactive
创建的另一个 proxy,它也会返回 true
。
import { reactive, isReactive, readonly } from 'vue' export default { setup() { const state = reactive({ name: 'John' }) // 从普通对象创建的只读 proxy const plain = readonly({ name: 'Mary' }) console.log(isReactive(plain)) // -> false // 从响应式 proxy 创建的只读 proxy const stateCopy = readonly(state) console.log(isReactive(stateCopy)) // -> true } }
isReadonly
检查对象是否是由readonly
创建的只读 proxy。
toRaw
返回 reactive
或 readonly
proxy 的原始对象。这是一个转义口,可用于临时读取而不会引起 proxy 访问/跟踪开销,也可用于写入而不会触发更改。不建议保留对原始对象的持久引用。请谨慎使用。
const foo = {} const reactiveFoo = reactive(foo) console.log(toRaw(reactiveFoo) === foo) // true
ref
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value
。
示例:
const count = ref(0) console.log(count.value) // 0 count.value++ console.log(count.value) // 1
如果将对象分配为 ref 值,则可以通过 reactive 方法使该对象具有高度的响应式。
类型声明:
interface Ref<T> { value: T } function ref<T>(value: T): Ref<T>
有时我们可能需要为 ref 的内部值指定复杂类型。我们可以通过在调用 ref
来覆盖默认推断时传递一个泛型参数来简洁地做到这一点:
const foo = ref<string | number>('foo') // foo's type: Ref<string | number> foo.value = 123 // ok!
如果泛型的类型未知,建议将 ref
转换为 Ref<T>
:
function useState<State extends string>(initial: State) { const state = ref(initial) as Ref<State> // state.value -> State extends string return state }
unref
如果参数为 ref
,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val
。
function useFoo(x: number | Ref<number>) { const unwrapped = unref(x) // unwrapped 确保现在是数字类型 }
toRef
可以用来为源响应式对象上的 property 新创建一个 ref
。然后可以将 ref 传递出去,从而保持对其源 property 的响应式连接。
const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') fooRef.value++ console.log(state.foo) // 2 state.foo++ console.log(fooRef.value) // 3
当您要将 prop 的 ref 传递给复合函数时,toRef
很有用:
export default { setup(props) { useSomeFeature(toRef(props, 'foo')) } }
toRef
可以用来为源响应式对象上的 property 新创建一个 ref
。然后可以将 ref 传递出去,从而保持对其源 property 的响应式连接。
const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') fooRef.value++ console.log(state.foo) // 2 state.foo++ console.log(fooRef.value) // 3
当您要将 prop 的 ref 传递给复合函数时,toRef
很有用:
export default { setup(props) { useSomeFeature(toRef(props, 'foo')) } }
toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的ref
。
const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) /* Type of stateAsRefs: { foo: Ref<number>, bar: Ref<number> } */ // ref 和 原始property “链接” state.foo++ console.log(stateAsRefs.foo.value) // 2 stateAsRefs.foo.value++ console.log(state.foo) // 3
当从合成函数返回响应式对象时,toRefs
非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行分解/扩散:
function useFeatureX() { const state = reactive({ foo: 1, bar: 2 }) // 逻辑运行状态 // 返回时转换为ref return toRefs(state) } export default { setup() { // 可以在不失去响应性的情况下破坏结构 const { foo, bar } = useFeatureX() return { foo, bar } } }