customRef

  • 用于顶一个ref,显示控制依赖和触发响应,接受一个工厂函数(返回对象),参数为track追踪,trigger触发响应
  • 官网的例子是做了一个防抖
<input v-model="text" />
 function unDebounced(value, delay = 2000) {
  let timer
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newVal) {
        clearTimeout(timer)
        timer = setTimeout(() => {
          value = newVal
          // do something
          console.log(value)
          trigger()
        }, delay)
      }
    }
  })
}
export default {
  setup() {
    return {
      text: useDebouncedRef('hello'),
    }
  },
}

markRaw

  • 显式标记一个对象为“永远不会转为响应式代理”,函数返回这个对象本身。
const foo = markRaw({})
console.log(isReactive(reactive(foo))) // false

// 如果被 markRaw 标记了,即使在响应式对象中作属性,也依然不是响应式的
const bar = reactive({ foo })
console.log(isReactive(bar.foo)) // false
// vue3中的响应式数据是统一改变return中的,
//所以如果你通过方法单独改变markRaw定义的数据,它是不会改变
//但是你后面又触发了响应式数据,那么之前未改变的markRaw定义的数据也会改变。例如这个:
<div @click="foos.num += 1">{{ foos.num }} ---reactive定义的响应式数据</div>
  <div @click="bar.num += 1">{{ bar.num }}---markRaw定义的非响应式数据</div>
// 如果你点击第二个div,数据不会改变;但是当点击第一个,这两个div的数据会一起改变,因为返回的数据都是return中的。

shallowReactive

  • 只为某个对象的私有(第一层)属性创建浅层的响应式代理,不会对“属性的属性”做深层次、递归地响应式代理,而只是保留原样。
const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2,
  },
})

// 变更 state 的自有属性是响应式的
state.foo++
// ...但不会深层代理
isReactive(state.nested) // false
isReactive(state.state ) // true
// 只有第一层是响应式的

ref,reactive都是创建深层次响应式数据

shallowReadonly

  • 只为某个对象的自有(第一层)属性创建浅层的只读响应式代理,同样也不会做深层次、递归地代理,深层次的属性并不是只读的。
  • 第一层是只读,深层可改变

shallowRef

  • 创建一个 ref ,将会追踪它的 .value 更改操作,但是并不会对变更后的 .value 做响应式代理转换(即变更不会调用 reactive
  • ref中传入的如果是一个对象,那么将调用reactive方法转换为响应式
const foo = shallowRef({})
// 更改对操作会触发响应
foo.value = {}
// 但上面新赋的这个对象并不会变为响应式对象
isReactive(foo.value) // false

toRaw

  • 返回由 reactive 或 readonly 方法转换成响应式代理的普通对象。这是一个还原方法,可用于临时读取,访问不会被代理/跟踪,写入时也不会触发更改。不建议一直持有原始对象的引用。请谨慎使用。
const foo = {}
const reactiveFoo = reactive(foo)

console.log(toRaw(reactiveFoo) === foo) // true

爬。