Devifish

  • 首页
  • Develop
  • Windows
  • Linux
  • Android
  1. 首页
  2. Develop
  3. 正文

在 Vue3 实现deepComputed(深计算)

2021年9月12日 1270点热度 3人点赞 0条评论

使用Vue时,一直都有一个令人头疼的问题。v-model 了一个computed参数无法调用其set函数进行修改。 从而导致Vuex使用起来非常麻烦,需要一个参数一个参数进行computed。而这个问题在Vue3上可以得到解决。

话不多说,先贴上代码:

/**
 * 深computed实现
 * 将传入的整个Obj转换成computedObj
 * 并使用reactive去除ref
 *
 * @param get getter
 * @param set setter
 * @param ignoreKey 忽略转换的Key
 * @returns computedObj
 */
export function deepComputed<T extends object, K extends keyof T>(
  get: () => T,
  set?: (newObj: T, key: string, newVal: any) => void,
  ...ignoreKeys: K[]
): Option<T> {
  const obj = get(),
    keys = Object.keys(obj),
    tempObj: Option<T> = Object.create(null)

  const isWrite = typeof set === "function"
  for (let key of keys) {
    if (ignoreKeys.includes(key as K)) {
      continue
    } else if (isWrite) {
      tempObj[key] = computed({
        get: () => get()[key],
        set: newVal => {
          const newObj = Object.assign({}, get(), { [key]: newVal })
          set(newObj, key, newVal)
        }
      })
    } else {
      tempObj[key] = computed(() => get()[key])
    }
  }

  return reactive(tempObj)
}

实现其实非常简单,就是遍历对象按需求转换成computed并重新赋值到新对象。 这个可以实现转换成computedObj,但是这样实现的方式只适用于只读 (赋值后会覆盖掉该参数的computed实现),只读也没必要把整个对象成员转换成computedObj。

而在 Vue3 上有响应式的实现reactive, 我们只需要把computedObj转换成响应式对象。

return reactive(tempObj)

在这样处理这之后,Vue会代理该对象。在对象进行赋值时参数会传递到Vue响应式实现的代理,代理会进行判断处理对象内的computed get set。

从而解决了之前赋值问题。

例子

<setting-item lable="导航栏" horizontal>
    <a-switch v-model:checked="topSiteSetting.enable" />
</setting-item>


const topSiteSetting = deepComputed(
  () => store.state.setting.topSite,
  updateTopSiteSetting,
  ...otherKeys(store.state.setting.topSite, "col", "row", "gap", "enable")
)

function updateTopSiteSetting(data: Option<TopSiteSetting>) {
  store.commit(SettingMutations.updateTopSiteSetting, data)
}

使用就如同原生computed, set回调更新后的newObj key value。

标签: 暂无
最后更新:2021年9月12日

devifish

这个人很懒,什么都没留下

点赞
< 上一篇

文章评论

取消回复

COPYRIGHT © 2021 devifish.cn. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

赣ICP备20010276号