生成AST(一)-正则说明
正则部分说明
正则基础知识了解:链接
属性匹配attribute
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>]+)))?/`
^\s*:前面可以存在0-n个空格([^\s"'<>\/=]+):匹配1个或多个 非 【空格、双引号、单引号、左右尖括号、/、=】(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>]+)):匹配属性值的各种情况"([^"]*)"+:匹配双引号括起来的字符串,以"(开头,[^"]*中间不是“的0-N个字符,以)"结束,+表示1个或者多个'[^']*'+:匹配单引号括起来的字符串[^\s"'=<>]+:匹配不包含空白字符、引号、等号、尖括号和反引号的一组或多组字符。
<template>
<div attributeName="value"></div> // 第一种---双引号
<div v-bind:attributeName='value'></div> // 第二种---单引号
<div type="checkbox" checked></div> // 第三种---没有单引号也没有双引号
<div :tab-index=1 checked></div> // 第三种---没有单引号也没有双引号
</template>
动态属性匹配dynamicArgAttribute
const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>]+)))?/、`
匹配规则其实跟标签匹配规则类似,只是修改了属性名称的匹配。
^\s*:前面可以存在0-n个空格((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*):匹配属性名称部分v-[\w-]+:|@|:|#:匹配以v-开头、紧接着是字母、数字、横线或下划线的属性前缀,或者以@、:或#开头的属性前缀。例如,v-bind:xxx、@click.xxx、:xxx、#xxx等\[:匹配一个左方括号[。[^=]+?:匹配一个或多个非等号字符,非贪婪模式。\]:匹配一个右方括号]。[^\s"'<>\/=]*:匹配零个或多个非空白字符、引号、尖括号、斜杠和等号。
(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>]+)))?:这部分匹配规则和attribute ` 标签名匹配规则一样。不再做阐述
标签名ncname
const ncname = [a-zA-Z_][\-\.0-9_a-zA-Z${unicodeRegExp.source}]*``
[a-zA-Z_]:匹配以字母或下划线开头的字符。[\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*:匹配零个或多个由连字符、点号、数字、下划线、字母或Unicode字符组成的字符。unicodeRegExp.source:一个动态生成的正则表达式,用于匹配Unicode字符
综合来说,这个规则匹配结果为true的字符串可以有:
div、span、p、_test ,my-component、v1.2.3、name_with_underscores ,中文标签
命名空间标签qnameCapture
const qnameCapture = ((?:{ncname})``
可能很多人没有听说过命名空间标签,其实在看源码这里之前我也是没有听过的。命名空间是Vue2用来解决多个组件名称相同的冲突。但是官方在Vue3版本中使用了Composition API来解决组件名称冲突的问题,不再支持这种写法。vue2中具体的使用写法如下:
<template>
<div>
<!-- 组件内容 -->
</div>
</template>
<script>
export default {
name:'MyComponent',
namespace: 'myNamespace', // 设置组件的命名空间
// 组件的其它选项
}
</script>
// 其他组件引用
<myNamespace:MyComponent></myNamespace:MyComponent>
qnameCapture 正则规则(?:${ncname}\\:) 中匹配了命名空间标签的规则,
(?:${ncname}\\:)?:匹配0-N次,以标签规则字符串为开头,后面需要跟上冒号:${ncname}:满足标签规则的字符串
startTagOpen
const startTagOpen = new RegExp(^<${qnameCapture})
开始标签的起始匹配,以<开头,后面需要跟着标签名称,如
startTagClose
const startTagClose = /^\s*(\/?)>/
开始标签的闭合匹配,匹配标签闭合地方,> 前面可以有空格,如:div >
标签结束匹配endTag
const endTag = new RegExp(^<\/${qnameCapture}[^>]*>)
^<\\/:以</开头[^>]*: 一个或多个 非>的字符串
如</div>,</myNamespace:MyComponent>
其他小知识点
v-pre
v-pre主要用于静态模板 和忽略特殊字符 的情况,一旦添加了v-pre指令,vue编译器将跳过对标记元素和其子元素的编译,不进行数据绑定和指令解析,从而提升编译性能。
<template v-pre>
<!-- 静态的模板内容 -->
</template>
<div v-pre>
<!-- 该元素及其子元素都会被跳过编译 -->
</div>
自闭合标签
第一种情况:html原本的一些自闭合标签如:<br>、<img>
第二种情况:vue中申明的一些组件标签<my-conponent />