vue3.4.0-alpha.1 其他变动

2,106 阅读3分钟

在上文中,我们讲了vue3.4.0-alpha.1 响应式逻辑的变动

我们接下来讲剩下的两处变动。

导出错误代码

我们可以通过

import { errorMessages, DOMErrorMessages } from "@vue/compiler-dom"

来获取errorCode对应的错误信息。

DOMErrorMessages是在compiler-dom包定义并导出的。

export const DOMErrorMessages: { [code: number]: string } = {
  [DOMErrorCodes.X_V_HTML_NO_EXPRESSION]: `v-html is missing expression.`,
  [DOMErrorCodes.X_V_HTML_WITH_CHILDREN]: `v-html will override element children.`,
  [DOMErrorCodes.X_V_TEXT_NO_EXPRESSION]: `v-text is missing expression.`,
  [DOMErrorCodes.X_V_TEXT_WITH_CHILDREN]: `v-text will override element children.`,
  [DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
  // 省略其他
  // .....
}

DOMErrorMessages包含的是与模板中的DOM操作相关的错误信息。通常与特定的Vue指令(例如 v-htmlv-textv-model 等)以及模板中的DOM结构有关。

比如使用 v-html 时没有提供表达式、v-model 用在不支持的元素上等。他们通常发生在编译器处理模板指令时,涉及到模板和DOM操作的结合。

errorMessages是在compiler-core包定义并导出的。

export const errorMessages: Record<ErrorCodes, string> = {
  // parse errors
  [ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT]: 'Illegal comment.',
  [ErrorCodes.CDATA_IN_HTML_CONTENT]:
    'CDATA section is allowed only in XML context.',
  [ErrorCodes.DUPLICATE_ATTRIBUTE]: 'Duplicate attribute.',
  [ErrorCodes.END_TAG_WITH_ATTRIBUTES]: 'End tag cannot have attributes.',
  [ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS]: "Illegal '/' in tags.",
  [ErrorCodes.EOF_BEFORE_TAG_NAME]: 'Unexpected EOF in tag.',
  [ErrorCodes.EOF_IN_CDATA]: 'Unexpected EOF in CDATA section.',
  [ErrorCodes.EOF_IN_COMMENT]: 'Unexpected EOF in comment.',
  // 省略其他
  // .....
}

同时compiler-dom包引入compiler-core包并导出,因此errorMessagesDOMErrorMessages都可以在compiler-dom包中获取。

errorMessages 包含的是一些通用的、与Vue模板编译器相关的错误信息。这些错误信息通常涵盖了模板语法的基本规则,以及编译器在处理模板时的一般性错误。他们与模板的结构和语法有关,例如标签闭合、属性使用等。他们代表了一些核心的编译器错误,不仅仅局限于特定的DOM操作。在编译器的各个阶段都可能出现这些错误。

同时,我们可以使用

import { ErrorTypeStrings } from "@vue/runtime-core"

来获取errorCode对应的错误信息。

ErrorTypeStrings是在runtime-core包定义并导出的。

export const ErrorTypeStrings: Record<LifecycleHooks | ErrorCodes, string> = {
  [LifecycleHooks.SERVER_PREFETCH]: 'serverPrefetch hook',
  [LifecycleHooks.BEFORE_CREATE]: 'beforeCreate hook',
  [LifecycleHooks.CREATED]: 'created hook',
  [LifecycleHooks.BEFORE_MOUNT]: 'beforeMount hook',
  [LifecycleHooks.MOUNTED]: 'mounted hook',
  // 省略其他
  // .....
}

ErrorTypeStrings用于描述生命周期钩子函数(LifecycleHooks)和编译器错误代码(ErrorCodes)对应的字符串表示。包含了Vue组件在不同阶段触发的生命周期钩子,以及编译器可能抛出的错误代码。这些字符串描述用于标识在Vue应用程序中可能出现的不同生命周期阶段和编译阶段的错误和事件。

在生产环境中,当我们遇到特定的errorCode时,可以使用导出的errorMessagesDOMErrorMessagesErrorTypeStrings来获取对应的错误信息,这样能够更方便地定位问题并进行修复。

once

watchoptions增加了一个参数once,代表这个watch只会触发一次,之后不会再次触发。

在增加这个参数之前,我们可以使用以下逻辑来实现只触发一次的watch

import { watch, ref } from "vue"
const num = ref(0)

const stop = watch(num, (newVal, oldVal) => {
  console.log(newVal, oldVal)
  stop()
})

let times = 0

const timer = setInterval(() => {
  times++
  if (times >= 2) {
    clearInterval(timer)
  }
  num.value++
}, 100)

//1 0

在增加once之后,我们可以直接将stop省略掉。

watch(num, (newVal, oldVal) => {
  console.log(newVal, oldVal)
}, { once: true })

让代码看起来更加优雅(pr原话)。

而改动代码也是比较简洁。

// doWatch
  if (cb && once) {
    const _cb = cb
    cb = (...args) => {
      _cb(...args)
      unwatch()
    }
  }

doWatch中,重新包装回调函数,当存在回调函数以及once的时候,自动调用unwatch

其实就是第一个例子,不同的是当使用once的时候,vue会自动替你做这些事情,避免了手动管理停止的麻烦,减少了出错的可能性。