阅读 6205

Vue 3.1.0 的 beta 版发布

以往都是翻译给大家,这次换个形式为大家介绍。

本文由 QC-LKnowsCount 完成编写和编辑工作。

VueConf 2021将于2021年5月22日在杭州举办,线上线下同步进行,尤雨溪将做主题演讲。抢票地址:vue.w3ctech.com

本次 beta 版本带来了一些有趣的新特性和错误修复。

新特性

  • onServerPrefetch:composition-api 版本的 serverPrefetch
  • 组件级别的 compilerOptions
  • @vue/compiler-core 支持了空白字符处理策略
  • 支持通过 app.config.compilerOptions 配置运行时的编译器
  • devtools 改进了对 KeepAlive 的支持
  • 支持通过 is="vue:xxx" 将普通元素转换为组件

onServerPrefetch

具体请参见 PR 3070PR 2902

此特性主要解决在 composition-api 情况下没有提供 serverPrefetch 生命周期钩子函数的问题。

这个钩子函数名为 onServerPrefetch

如果你也这方面的需求,可以尝试升级至 3.1.0-beta

相关讨论:

@vue/complier-core 支持了空白字符处理策略

具体内容请参阅 PR 1600v2 原有效果

应用

我们来测试下此策略:

先装个 beta 版本的 @vue/compiler-core

yarn add @vue/compiler-core@beta
复制代码

新建 index.js 文件

const core = require('@vue/compiler-core')

const { baseCompile: complie } = core

const { ast } = complie(`      foo \n bar baz      `, {
  whitespace: 'preserve' // condense
})

console.log(ast.children[0])
console.log(ast.children[0].content)
复制代码

大概效果如示例所示:

<!-- 源代码 -->
      foo \n bar baz     

<!-- whitespace: 'preserve' -->
      foo \n bar baz     

<!-- whitespace: 'condense' -->
 foo bar baz 
复制代码

源码

原本只在 compiler-coreparse 文件中的 defaultParserOptions 提供了默认的 condense 情况

whitespace: 'condense'
复制代码

compiler-core 的 options 文件中新增了 whitespace

whitespace?: 'preserve' | 'condense'
复制代码

相关链接:

通过 is="vue:xxx" 支持普通元素的转换

这条特性的更新,从源码上看,兼容了两种类型。

  1. 弃用的 v-is 指令
  2. is="vue:xxx" 的属性

源码


let { tag } = node

// 1. 动态组件
const isExplicitDynamic = isComponentTag(tag)
const isProp =
  findProp(node, 'is') || (!isExplicitDynamic && findDir(node, 'is'))
if (isProp) {
  if (!isExplicitDynamic && isProp.type === NodeTypes.ATTRIBUTE) {
    // <button is="vue:xxx">
    // 如果不是 <component>,仅仅是 "vue:" 开头
    // 在解析阶段会被视为组件,并在此处进行
    // tag 被重新赋值为 "vue:" 以后的内容
    tag = isProp.value!.content.slice(4)
  } else {
    const exp =
      isProp.type === NodeTypes.ATTRIBUTE
        ? isProp.value && createSimpleExpression(isProp.value.content, true)
        : isProp.exp
    if (exp) {
      return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
        exp
      ])
    }
  }
}
复制代码
// 当 tag 为 <component>,或者 is="vue:xxx",跳过后续处理
if (
  name === 'is' &&
  (isComponentTag(tag) || (value && value.content.startsWith('vue:')))
) {
  continue
}
// ...
复制代码

上述代码中有几个点:

  1. 首先 isComponentTag,用以判断是否为动态组件:
// 此方法用于判断是否为动态组件
function isComponentTag(tag: string) {
  return tag[0].toLowerCase() + tag.slice(1) === 'component'
}
复制代码
  1. 查找是否含有 is 属性
// 先查属性
findProp(node, 'is')
// 否则判断是不是动态组件,如果不是,判断是不是指令
!isExplicitDynamic && findDir(node, 'is')
复制代码

其主要原因是,两者的 AST 结构不同。

相关链接:

Bug 修复

  • 兼容: 处理并针对 config.optionMergeStrategies 实现告警 (94e69fd)
  • compiler-core: 当注释选项启用时,在生产环境下将保留注释 (e486254)
  • hmr: 禁止从组件类型中移除 __file 的 key 值 (9db3cbb)
  • hydration: 修复 asnyc 组件 hydrated 前的更新 (#3563) (c8d9683), closes #3560
  • reactivity: 修复 readonly + reactive Map 的追溯 (#3604) (5036c51), closes #3602
  • runtime-core: 确保声明 props 的 key 永远存在 (4fe4de0), closes #3288
  • runtime-core: 监听多源: computed (#3066) (e7300eb), closes #3068
  • Teleport: 避免改变对 vnode.dynamicChildren 的引用 (#3642) (43f7815), closes #3641
  • watch: 避免遍历 non-plain 对象 (62b8f4a)
  • watch: this.$watch 应该支持监听键路径 (870f2a7)

特性

  • onServerPrefetch (#3070) (349eb0f)
  • 运行时编译器支持了组件级 compilerOptions (ce0bbe0)
  • compiler-core: whitespace 处理策略 (dee3d6a)
  • config: 利用 app.config.compilerOptions 支持配置运行时编译器 (091e6d6)
  • devtools: 升级对 KeepAlive 的支持 (03ae300)
  • 支持利用 is="vue:xxx" 将 plain 元素 cast 到组件 (af9e699)

性能提升

  • 仅当实际改变时才会触发 $attrs 的更新 (5566d39)
  • compiler: 解析结束标签时跳过不必要的检查 (048ac29)
文章分类
前端
文章标签