昨天我们分析了setup
如何处理props
等,今天我们接着往下分析。
坏蛋Dan:vue/compiler-sfc源码分析学习--part2:如何处理script--day4
感兴趣的大佬可以看下
今天是分析如何处理script
的最后一天了,加油!
setup
的返回语句allBindings
: 俩script block
数据的集合。hasDefaultExportRender
: 是否有render
函数,比如这种{ render: (h) => {} }
。compileTemplate
: 来自./compileTemplate.ts
,看名字就知道是用来处理template
模板的。generateCodeFrame
: 生成错误提示语的,比如下划线标记之类的,这个就不看代码了,无关紧要。unref
[1]:前面应该漏了这玩意儿,它其实是一种语法糖,是val = isRef(val) ? val.value : val
的简写。这一大段其实做的事情很简单,就是判断你是使用template
还是inlineTemplate
还是使用的render
函数。
由于我们用的是常规的template
,所以这里只会走第一部分的逻辑。
可以看到returned
实际上就是我们的变量、函数、类、导入的方法等。不过有一点需要注意,那就是defineProps
、defineEmits
以及defineExpose
的都不在这里面。至于他们会在哪,后面会说到。
至于inline
或者render
函数方式,我们有空再分析。
export default
hasDefaultExportName
: 之前分析non script block
的时候有说到过,这里就是判断你export
的对象中是否有name
字段。为啥这里一定要有个name
呢?因为方便vue-tool
在浏览器生成节点时命名节点。hasInlinedSsrRenderFn
: 和ssr
相关的,是否有ssr
的render
函数,我们不会分析ssr
相关的,所以这里忽略。propsRuntimeDecl
: 老朋友了,当然如果忘了这里再说下,就是你传入defineProps
中的对象。propsDestructureDecl
: 也是老朋友了,props
解构赋值的那个节点。propsDestructuredBindings
:节点转换成的数据genDestructuredDefaultValue
: 看名字就知道是用来获取解构赋值中的默认值的。helper
: 前面也说过了,将runtime
辅助函数存储到helperImport
中。propsTypeDecl
: defineProps
使用only-type
场景的类型定义。genRuntimeProps
: 代码就不看了,简单的说下做了什么,里面会根据你的类型定义转化成runtime
的props
,毕竟浏览器不认识ts
。另外还有个点我把代码贴出来除了是boolean
类型或者带有默认值的函数类型需要保留之外,其余的都会移除类型定义。
emitsRuntimeDecl
: 同props
。emitsTypeDecl
: 同上。hasDefineExposeCall
: 前面好像没说过?这个是判断是否用了defineExpose
的,会被转换成export default
对象中的expose()
方法。defaultExport
: 默认导出的,比如export { xx as default } from 'xx.js'
。hasAwait
: 是否有直接在setup block
中使用await
的,这个也是之前文章中提到好几次的,这里就不说如何处理这个场景的了,总之是允许你在setup
语法糖下直接await
而不需要async
的。这一大段看完代码估计大家都知道是在干啥了吧?
将之前的数据组装成非setup
语法糖的样子,不多说,直接看数据。另外有个点就是之前的__default__
,这里面包括non setup block
的export
以及别的包导入的比如export { x as default } from 'xx'
,最终都会合并到一起再export default
导出。
而最终转换的script
代码由于太长,这里就直接以代码的形式贴出来。
这回一目了然了,感觉前面说的一堆解析还不如这里直接贴出来最终代码。
这里有几处地方你们应该注意到了
import
的语句包括non setup script block
中的import
都会被移动到头部,也就是顶级作用域。export { x as default } from 'xx'
或者non setup block
中的export default
都会被合并到__default__
中,然后和我们的setup block
中的export default
合并组合成最终的export default
setup
函数中return
出去的东西是包括non setup block
的defineExpose
会被转换为expose
方法defineProps、defineEmits
等方法的import
都被移除了,实际上并不需要开发者去导入。props、emits
的定义都会被移到setup
外部,这也就解释了为什么你在defineProps、defineEmits
中引用local
变量(setup
函数中的变量)会报错了。props、emits、expose
赋值给的变量都会被处理迁移到setup
函数的参数中,上面埋下的坑这里补上了。setup block
中直接使用await
的会被处理成一个立即执行函数,具体怎么做之前的文章里有说。await
,这里setup
函数会给你加上async
。css
变量会被处理成一个带有scopedId
的字段,然后在组件创建时执行,具体怎么做的,之前的文章里也有说到过了,这里就不多说了。$ref
语法糖被处理成ref
,连同xxx = aa
被处理成xxx.value = aa
。这个就不多说了,我们直接看下数据
这些都是runtime
需要的辅助函数
这里面就mergeDefaults
没说过,不过这个简单说就是合并默认值的操作。
没啥好说的。。。
今天是分析如何处理script
的最后一天,我们终于看到了最终的代码长啥样了。
简单的说主要就是在将setup
语法糖处理成非语法糖的样子,这里面最麻烦的就是props
的处理了。。
发布于 2022-12-05 16:59・IP 属地广东