2、vue3-响应式 API:工具函数

75 阅读4分钟

响应式基础

1、shallowRef()

  • 是ref() 的浅层作用形式。
  • 常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。
const state = shallowRef({ count: 1 })
// 不会触发更改
state.value.count = 2
// 会触发更改
state.value = { count: 2 }

2、isRef()

  • 检查某个值是否为 ref。
let name = ref('哈哈');
let state = shallowRef({ count: 1 })
isRef(name);//true
isRef(state);//true
isReactive(state);//false

3、unref()

  • 如果参数是 ref,则返回内部值,否则返回参数本身。
  • 这是 val = isRef(val) ? val.value : val 计算的一个语法糖。

4、shallowReactive()

  • 是reactive() 的浅层作用形式。
  • 常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。
const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2
  }
})

// 更改状态自身的属性是响应式的
state.foo++

// ...但下层嵌套对象不会被转为响应式
isReactive(state.nested) // false

// 不是响应式的
state.nested.bar++

5、isReactive()

  • 检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。
let age = reactive({name:'哈哈'});
isReactive(age);//true
isRef(age);//false

6、toRef()

  • toRef 用于从响应式对象中提取一个属性,并将其转换为一个 ref 对象
  • 这个 ref 对象会与原始属性保持同步:修改 ref 对象的值会更新原始属性,反之亦然。
  • 主要针对赋值给一个新的变量,让其也保持同步的响应。
const state = reactive({
  foo: 1,
  bar: 2,
});

//如果直接赋值,fooRef会与state.foo会断掉响应式,修改fooRef,state中的foo不变
const fooRef = state.foo;
//使用toRef赋值,fooRef是和原state中的foo保持响应的,修改fooRef,state中的foo同步
const fooRef = toRef(state, 'foo');

7、toRefs()

  • 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref
  • 解构赋值很有用,可以保持同步的响应。
  • 和上面的toRef功能一样,这个是1对应多
let obj = ref({name:'哈哈'});
let {myName} = toRefs(obj);//这里的myName和obj.name 保持同步的响应
let myName = obj.name;//这里的myName和obj.name 不能保持同步的响应

8、shallowReadonly()

  • readonly() 的浅层作用形式
  • 和 readonly() 不同,这里没有深层级的转换:只有根层级的属性变为了只读。属性的值都会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。
  • 谨慎使用

9、isReadonly()

  • 检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。
  • 通过 readonly()shallowReadonly() 创建的代理都是只读的,类似于没有 set 函数的 computed() ref。

10、isProxy()

  • 检查一个对象是否是由 reactive()readonly()shallowReactive()shallowReadonly() 创建的代理
let aa = ref(3);
let cc = toRef(bb,'name')
console.log(isProxy(aa.value));//false
console.log(isProxy(cc));//false

let bb = reactive({name:'aa'})
console.log(isProxy(bb));//true

11、toRaw()

  • 根据一个 Vue 创建的代理返回其原始对象。
  • 方便阅读
let bb = reactive({name:'哈哈'})
console.log(bb);//Proxy {name: "哈哈"}
console.log(toRaw(bb));//{name: "哈哈"}

12、toValue()

  • 仅在 3.3+ 中支持
  • 将值、refs 或 getters 规范化为值。这与 unref() 类似,不同的是此函数也会规范化 getter 函数。如果参数是一个 getter,它将会被调用并且返回它的返回值。
  • 这可以在组合式函数中使用,用来规范化一个可以是值、ref 或 getter 的参数。

以下不常用

1、triggerRef()

  • 强制触发依赖于一个浅层 ref 的副作用,这通常在对浅引用的内部值进行深度变更后使用。

2、customRef()

  • 创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式。

3、markRaw()

  • 将一个对象标记为不可被转为代理。返回该对象本身。

4、effectScope()

  • 创建一个 effect 作用域,可以捕获其中所创建的响应式副作用 (即计算属性和侦听器),这样捕获到的副作用可以一起处理。

5、getCurrentScope()

  • 如果有的话,返回当前活跃的 effect 作用域。

6、onScopeDispose()

  • 在当前活跃的 effect 作用域上注册一个处理回调函数。当相关的 effect 作用域停止时会调用这个回调函数。
  • 这个方法可以作为可复用的组合式函数中 onUnmounted 的替代品,它并不与组件耦合,因为每一个 Vue 组件的 setup() 函数也是在一个 effect 作用域中调用的。
  • 如果在没有活跃的 effect 作用域的情况下调用此函数,将会抛出警告。在 3.5+ 版本中,可以通过将第二个参数设为 true 来消除此警告。