[踩坑记录] Vue3 customRef 传入对象没有进入set方法

问题描述

学习Vue3 Ref 相关 API 的时候,遇到了 customRef 这个 API,它可以让我们自定义 ref 的更新的过程

但是使用 customRef 有一个问题就是,如果你传入的是初始值,那么一切正常,如果你传入的是一个对象,那 set 函数将会不起作用

customRef 简单使用

function myRef<T>(value: T) {
      return customRef((track, trigger) => {
        return {
          get() {
            // do something
            // 跟踪
            // console.log('track');
            track();
            return value;
          },
          set(newValue) {
            // also do something
            console.log('update')
            value = newValue;
            trigger();
          },
        };
      });
    }

    const azouxCustom = myRef('custom');
    const azouxCustomObject = myRef({ name: 'obj' });
    azouxCustom.value = '123'; // 一切正常
    azouxCustomObject.value.name = 'yoyoyo'; // NOT WORK

原因分析

如果我们传入的是对象,那么实际上 Value 记录的是一个地址值,我们在 set 方法中进行的 value = newValue 本质上只是给一个对象赋了它原本的地址值,因此不会更新

但是为什么连set方法都没有进去呢?原因应该是customRef底层用的是shallowRef(有待考证),是一个浅层更新,深层次的数据更新不会触发视图更新,因此就不会进入set方法

解决方法

  • triggerRef()
  • 直接替换 value

triggerRef

使用 triggerRef 只需要在我们更新属性值之后强制刷新一下ref对象即可

      azouxCustomObject.value.name = 'azzz';
      triggerRef(azouxCustomObject); // 之后会进入 set 方法,并触发视图更新

直接替换 value

      azouxCustomObject.value = { name: 'aaa' }; // 这样也可以触发视图更新
posted @ 2022-10-06 23:00  azoux  阅读(135)  评论(0编辑  收藏  举报