一个实用小技巧,Vue3 中清晰打印 ref 、reactive 和 readOnly

1,803 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情

在开发 Vue3 时,打印一个变量,会打印一大堆东西,一点也不直观,如下例:

const count = ref(100)
const userInfo = reactive({ 
  name: 'lin',
  age: 18
})
console.log('count :>> ', count);
console.log('userInfo :>> ', userInfo);

image.png

针对这个问题,其实 Vue3 内部是做过优化的,可以点击浏览器控制台右侧的设置按钮,打开设置面板。

image.png

Console 这个选项下把 Enable custom formatters 设为勾选态。

image.png

再刷新浏览器,打印刚才的变量,就会简洁很多。

image.png

再看一个例子,readOnly 的对象,展示起来也很直观。

const userInfo = reactive({ 
  name: 'lin',
  age: 18
})
const _userInfo = readonly(userInfo)
console.log('userInfo :>> ', userInfo);
console.log('_userInfo :>> ', _userInfo);

image.png

这是如何做到的呢,其实浏览器的 console.log()是可以自定义的,具体可以看这两篇文章:

在 Vue3 中,自定义的逻辑主要写在 initCustomFormatter 方法里,对 ref、reactive和 readOnly 的变量做了自定义打印。

if ((window as any).devtoolsFormatters) {
    ;(window as any).devtoolsFormatters.push(formatter)
  } else {
    ;(window as any).devtoolsFormatters = [formatter]
  }
const formatter = {
    header(obj: unknown) {
      // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
      if (!isObject(obj)) {
        return null
      }

      if (obj.__isVue) {
        return ['div', vueStyle, `VueInstance`]
      } else if (isRef(obj)) {
        return [
          'div',
          {},
          ['span', vueStyle, genRefFlag(obj)],
          '<',
          formatValue(obj.value),
          `>`
        ]
      } else if (isReactive(obj)) {
        return [
          'div',
          {},
          ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
          '<',
          formatValue(obj),
          `>${isReadonly(obj) ? ` (readonly)` : ``}`
        ]
      } else if (isReadonly(obj)) {
        return [
          'div',
          {},
          ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
          '<',
          formatValue(obj),
          '>'
        ]
      }
      return null
    },
    hasBody(obj: unknown) {
      return obj && (obj as any).__isVue
    },
    body(obj: unknown) {
      if (obj && (obj as any).__isVue) {
        return [
          'div',
          {},
          ...formatInstance((obj as ComponentPublicInstance).$)
        ]
      }
    }
  }

可以看出,Vue 对于用户体验确实是下了功夫的。

结尾

本文参考:Vue.js设计与实现

阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

我是阿林,输出洞见技术,再会!