reactive相关知识点

151 阅读1分钟

reactive

作用

接收数组或者对象,将其中的属性转为响应式属性

使用

import { reactive } from 'vue'
const info = reactive({})
const info = reactive([])

原理

reactive

如果传入的是响应式对象,则直接返回,否则调用createReactiveObject函数

export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
export function reactive(target: object) {
  // if trying to observe a readonly proxy, return the readonly version.
  if (target && (target as Target)[ReactiveFlags.IS_READONLY]) {
    return target
  }
  return createReactiveObject(
    target,
    false,
    mutableHandlers,
    mutableCollectionHandlers,
    reactiveMap
  )
}

createReactiveObject

reactive传入的参数传入该函数

function createReactiveObject(
  target: Target,
  isReadonly: boolean, // 是否是isReadlyOnly
  baseHandlers: ProxyHandler<any>, // 用于Object、Array创建proxy
  collectionHandlers: ProxyHandler<any>, // 用于Set、Map创建proxy
  proxyMap: WeakMap<Target, any> // WeakMap
) {
  // 如果target不是对象,则报一个警告
  if (!isObject(target)) {
    if (__DEV__) {
      console.warn(`value cannot be made reactive: ${String(target)}`)
    }
    return target
  }
  // target is already a Proxy, return it.
  // exception: calling readonly() on a reactive object
  if (
    target[ReactiveFlags.RAW] &&
    !(isReadonly && target[ReactiveFlags.IS_REACTIVE])
  ) {
    return target
  }
  // target already has corresponding Proxy
  const existingProxy = proxyMap.get(target)
  if (existingProxy) {
    return existingProxy
  }
  // only a whitelist of value types can be observed.
  const targetType = getTargetType(target)
  if (targetType === TargetType.INVALID) {
    return target
  }
  // 如果是一个普通对象,则通过proxy创建代理进行监听
  const proxy = new Proxy(
    target,
    targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
  )
  proxyMap.set(target, proxy)
  return proxy
}

readOnly

作用

copy一份reactive数据为只读的,不能修改其中的属性

使用

import { reactive, readOnly } from 'vue'
const info = reactive({
    name: '张三'
})
const copy = readOnly(info)

原理

readOnly

reactive一样,只不过第二个参数为true,表示只读

export function readonly<T extends object>(
  target: T
): DeepReadonly<UnwrapNestedRefs<T>> {
  return createReactiveObject(
    target,
    true,
    readonlyHandlers,
    readonlyCollectionHandlers,
    readonlyMap
  )
}

shallowReactive

作用

同shallowRef,只会将对象或数组的第一层作为响应式监听,深层次的数据是不会监听的;注意,在数据挂载之前,对数据的深层次更改是会生效的,挂在之后再修改深层次的数据,数据会变,但是页面不会发生改变。

原理

shallowReactive

reactive一样,后面三个参数不同

export function shallowReactive<T extends object>(
  target: T
): ShallowReactive<T> {
  return createReactiveObject(
    target,
    false,
    shallowReactiveHandlers,
    shallowCollectionHandlers,
    shallowReactiveMap
  )
}