大家好,我是若川(点这里加我微信 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 } = coreconst { 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-core
的 parse
文件中的 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"
支持普通元素的转换
这条特性的更新,从源码上看,兼容了两种类型。
弃用的
v-is
指令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.expif (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
}
// ...
上述代码中有几个点:
首先
isComponentTag
,用以判断是否为动态组件:
// 此方法用于判断是否为动态组件
function isComponentTag(tag: string) {return tag[0].toLowerCase() + tag.slice(1) === 'component'
}
查找是否含有
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基础系列