sp3d数据VUE文件解析 .Vue格式文件解析,数据结构,算法解析。 源码

在咖啡凉透之前,我们聊聊如何手撕Vue单文件组件。作为现代前端开发的标配格式,.vue文件承载着模板、脚本、样式三位一体的魔法,但这份优雅背后藏着怎样的数据结构?

先看最简单的.vue文件结构:

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  data() {
    return { message: 'Hello Vue!' }
  }
}
</script>

<style scoped>
div { color: red; }
</style>

三剑客被特殊注释分隔,底层解析器需要先做块切割。咱们用正则开个场:

const splitRE = /<script\b[^>]*>([\s\S]*?)<\/script>|<style\b[^>]*>([\s\S]*?)<\/style>/gi

function parseSFC(content) {
  const blocks = []
  let lastIndex = 0
  
  content.replace(splitRE, (match, script, style, offset) => {
    blocks.push({
      type: 'template',
      content: content.slice(lastIndex, offset).trim()
    })
    if(script) blocks.push({ type: 'script', content: script })
    if(style) blocks.push({ type: 'style', content: style })
    lastIndex = offset + match.length
    return ''
  })

  return blocks
}

这个正则像把瑞士军刀,精准切开各区块。注意replace方法的妙用——表面上替换字符,实际在收集代码块位置信息。

模板解析才是重头戏,Vue3的@vue/compiler-dom包藏着玄机。看段模板AST生成:

import { parse } from '@vue/compiler-dom'

const ast = parse(`<div v-if="show" @click="handle">Hello</div>`)
console.log(ast.children[0].props)
// [
//   { type:7, name:'if', exp: { content: 'show' } },
//   { type:7, name:'onClick', exp: { content: 'handle' } }
// ]

生成的AST节点藏着编译线索:v-if被标记为指令类型7,事件监听器用@简写也能正确解析。模板中的动态绑定会被编译成渲染函数中的_createVNode调用。

处理scoped样式时,Vue玩了个障眼法:

/* 原始代码 */
div { color: red; }

/* 编译后 */
div[data-v-5e6e9c] { color: red; }

这个data-v哈希来自文件路径的哈希运算,确保样式作用域隔离。解析器在

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐