最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

谈谈 Vue shallowRef 和 shallowReactive

来源:博客园

深层次响应式

reactiveref创建的对象都是深层次的,对象的根属性和嵌套属性都是响应式的。

深层次转换是递归地转为响应式,对象里的每个属性访问都将触发代理的依赖追踪,这种性能负担通常这只有在处理超大型数组或层级很深的对象时才比较明显。例如,一次渲染需要访问 100000+ 个属性时,才会变得比较明显。因此,shallowRefshalloReactive只在少数特定的场景才会使用。

const state = reactive({  foo: {    bar: 1  },  foobar: 2});

浅层次响应式

shallowReactive

shallowReactive创建的响应式对象只在其根属性是响应式的,对所有深层的对象不会做任何的递归深层转换处理,否则和 reactive 没区别。


【资料图】

浅层响应式对深层级属性的访问会很快,但代价是,所有深层的对象视为非响应式的。

const state = shallowReactive({  foo: {    bar: 1  },  foobar: 2});

上图中,state.foo.bar没有发生改变,只有在其他响应式更新之后,才间接地更新它的状态。

替换顶级对象失去响应式

对于 reactiveshallowReactive,如果替换了顶级对象就会失去响应式:

let state = shallowReactive({  foo: {    bar: 1  },  foobar: 2});function changeState() {  state = {    foo: {      bar: 1000    },    foobar: 2000  };}

如上图所示,state.foobar在替换顶级对象之前,一直是有响应式的,但是被替换了之后,就失去了响应式。

需要思考的是,为什么替换了顶级对就失去了响应式,请先阅读 Vue 中的响应性是如何工作的,官方文档给了一个 reactive 和 ref 创建响应式的伪代码,不难看出,reactive 返回了一个 Proxy。在 getter/setter上加上 Vue 的追踪代码,实现响应式。

一旦这个 Proxy 对象被替换了,就没有了 getter/setter,即失去了响应式。

shallowRef

shallowReactive不同的是,shallowRef创建的响应式对象都是浅层的,并不是说它不是响应式,因为有 triggerRefAPI 存在,即主动地通知更新。

let state = shallowRef({  foo: {    bar: 1  },  foobar: 2});function changeState() {  state.value = {    foo: {      bar: 1000    },    foobar: 2000  };}

在替换顶层对象之前,点击按钮,state.foo.barstate.foobar都没有更新。强制通知浅层 ref 更新,可以使用 triggerRef,具体查看官方文档:triggerRef。

替换顶级对象不会失去响应式

shallowRefref创建的响应式对象被替换了之后,依旧保留响应式。

let state = shallowRef({  foo: {    bar: 1  },  foobar: 2});function changeState() {  // 自加不会触发页面更新  state.value.foo.bar++;  state.value.foobar++;  // 替换 state.value 的顶级对象页面才会更新  const replace = {    foo: {      bar: state.value.foo.bar    },    foobar: state.value.foobar  };  state.value = replace;}

最好的做法是通过 triggerRef,改造一下代码:

function triggerUpdate() {  state.value.foo.bar++;  state.value.foobar++;  triggerRef(state);}

总结 shallowRef

shallowReactive没有强制更新的 API,只有第一层属性是响应式的,且嵌套对象属性是间接触发更新的机制。

所以,想要一个浅层的响应式对象,建议使用 shallowRef,它有 triggerRef这样的 API,使用起来灵活。

什么时候用到浅层响应式

  1. 在处理大量数据,需要提高性能(优化性能)时;
  2. 不希望立马更新,需要自定义更新时机时。

关键词: