Vue 3.1.0 的 beta 版发布

大家好,我是若川(点这里加我微信 ruochuan12,长期交流学习)。昨晚尤大视频号直播说到vue 3.1.0 beta版发布了,今天分享这篇文章。也有小伙伴可能注意到了昨晚我一直在送礼物。

点击下方卡片关注我、加个星标,或者查看源码等系列文章。学习源码整体架构系列年度总结JS基础系列


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

编辑 | KnowsCount

         QC-L

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

新特性

  • onServerPrefetch:composition-api 版本的 serverPrefetch

  • 组件级别的 compilerOptions

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

  • 支持通过 app.config.compilerOptions 配置运行时的编译器

  • devtools 改进了对 KeepAlive 的支持

  • 支持通过 is="vue:xxx" 将普通元素转换为组件

onServerPrefetch

具体请参见 PR 3070[1] 和 PR 2902[2]

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

这个钩子函数名为 onServerPrefetch

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

相关讨论:

  • vue-apollo[3]

  • app-extension-apollo[4]

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

具体内容请参阅 PR 1600[5] 和 v2 原有效果[6]

应用

我们来测试下此策略:

先装个 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'

相关链接:

  • PR 1600[7]

  • stackoverflow[8]

  • vue 2.0/compiler[9]

  • vue 2.0 的 `whitespace`[10]

  • vue 2.0 的 PR[11]

通过 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 结构不同。

相关链接:

  • Support casting plain element[12]

  • Custom Elements Interop[13]

附上 ChangeLog

Bug 修复

  • 兼容: 处理并针对 config.optionMergeStrategies 实现告警 (94e69fd[14])

  • compiler-core: 当注释选项启用时,在生产环境下将保留注释 (e486254[15])

  • hmr: 禁止从组件类型中移除 __file 的 key 值 (9db3cbb[16])

  • hydration: 修复 asnyc 组件 hydrated 前的更新 (#3563[17]) (c8d9683[18]), closes #3560[19]

  • reactivity: 修复 readonly + reactive Map 的追溯 (#3604[20]) (5036c51[21]), closes #3602[22]

  • runtime-core: 确保声明 props 的 key 永远存在 (4fe4de0[23]), closes #3288[24]

  • runtime-core: computed 监听多个 source (#3066[25]) (e7300eb[26]), closes #3068[27]

  • Teleport: 避免改变对 vnode.dynamicChildren 的引用 (#3642[28]) (43f7815[29]), closes #3641[30]

  • watch: 避免遍历 non-plain 对象 (62b8f4a[31])

  • watch: this.$watch 应该支持监听键路径 (870f2a7[32])

特性

  • onServerPrefetch (#3070[33]) (349eb0f[34])

  • 运行时编译器支持了组件级 compilerOptions (ce0bbe0[35])

  • compiler-core: whitespace 处理策略 (dee3d6a[36])

  • config: 利用 app.config.compilerOptions 支持配置运行时编译器 (091e6d6[37])

  • devtools: 升级对 KeepAlive 的支持 (03ae300[38])

  • 支持利用 is="vue:xxx" 将 plain 元素 cast 到组件 (af9e699[39])

性能提升

  • 仅当实际改变时才会触发 $attrs 的更新 (5566d39[40])

  • compiler: 解析结束标签时跳过不必要的检查 (048ac29[41])

参考资料

[1]

PR 3070: https://github.com/vuejs/vue-next/pull/3070

[2]

PR 2902: https://github.com/vuejs/vue-next/pull/2902

[3]

vue-apollo: https://github.com/vuejs/vue-apollo/issues/1102

[4]

其余参考资料省略,可以点击阅读原文查看。


最近组建了一个江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你进群。


················· 若川出品 ·················

今日话题

昨晚尤大在视频号直播,估计挺多人看到直播了。估计看到直播的还是小部分,大部分还是不知道有这个直播。我一直在刷礼物,也是第一次看视频号刷礼物,我也不太懂视频号的玩法。后来才发现可以链接到视频号,还可以关联公众号,说不定还能涨几个粉。但我用的是第二个号没有视频号关联。平时知道有这个东西,但真正用起来又显得有点棘手。欢迎在下方留言~  欢迎分享、收藏、点赞、在看我的公众号文章~

一个愿景是帮助5年内前端人走向前列的公众号

可加我个人微信 ruochuan12,长期交流学习

推荐阅读

我在阿里招前端,我该怎么帮你?(现在还能加我进模拟面试群)

若川知乎问答:2年前端经验,做的项目没什么技术含量,怎么办?
据说 99% 的人不知道 vue-devtools 还能直接打开对应组件文件?本文原理揭秘

点击方卡片关注我、加个星标,或者查看源码等系列文章。
学习源码整体架构系列年度总结JS基础系列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值