Vue单文件组件 - 指南
一、什么是单文件组件(SFC)?
单文件组件(SFC) 是 Vue 提出的一种文件格式,允许我们将一个组件的模板、脚本和样式写在同一个
.vue文件中。
它不是浏览器原生支持的格式,而是通过构建工具(如 Vite、Webpack)在开发和构建时编译为标准的 JavaScript 模块。
基本结构
{{ title }}
<script>
export default {
name: 'HelloWorld',
data() {
return {
title: 'Hello Vue SFC',
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
</script>
✅ 一个
.vue文件 = 一个独立的 Vue 组件。
二、SFC 的三大组成部分详解
1. <template>:模板
- 定义组件的 HTML 结构。
- 支持 Vue 模板语法:
v-if、v-for、{{ interpolation }}等。 - 只能包含一个根元素(Vue 2),Vue 3 支持多根节点(Fragment)。
...
...
2. <script>:逻辑
- 定义组件的数据、方法、生命周期等。
- 可以是 Vue 2 的选项式 API,也可以是 Vue 3 的组合式 API。
Vue 2 风格(选项式)
<script>
export default {
data() { /* ... */ },
methods: { /* ... */ },
mounted() { /* ... */ }
}
</script>
Vue 3 风格(组合式 API + <script setup>)
<script setup>
import { ref, onMounted } from 'vue'
const count = ref(0)
const increment = () => count.value++
onMounted(() => {
console.log('组件已挂载')
})
</script>
✅
<script setup>是 Vue 3 推荐的语法,更简洁、更高效。
3. <style>:样式
- 定义组件的 CSS 样式。
- 支持
scoped、module、预处理器(Sass/Less/Stylus)等。
scoped:作用域样式
编译后:
<h1 data-v-f3f3eg9>+h1[data-v-f3f3eg9] { color: red; }
✅ 实现样式局部化,避免全局污染。
module:CSS Modules
Hello
✅ 更强的样式隔离,支持动态类名。
预处理器支持
✅ 使用 Sass、Less 等提升 CSS 开发效率。
三、SFC 是如何工作的?—— 编译原理
.vue 文件在开发时会被 Vue Loader(Webpack) 或 Vite 处理,编译为标准的 JavaScript 模块。
编译过程(简化版)
- 解析:将
.vue文件解析为 AST(抽象语法树)。 - 分离:提取
<template>、<script>、<style>。 - 转换:
<template>→ 编译为render函数<script>→ 导出组件对象<style scoped>→ 添加data-v-hash并重写 CSS 选择器
- 合并:生成一个 ES Module,供其他组件导入。
最终输出:一个包含
render函数、组件选项和 CSS 的 JS 模块。
四、为什么推荐使用 SFC?—— 核心优势
| 优势 | 说明 |
|---|---|
| ✅ 高内聚 | 模板、逻辑、样式集中管理,便于维护 |
| ✅ 可读性强 | 一个文件看全组件,无需跳转 |
| ✅ 工具支持好 | VSCode、WebStorm 有语法高亮、智能提示 |
| ✅ 热重载(HMR) | 修改后页面局部刷新,提升开发体验 |
| ✅ 作用域样式 | scoped 避免样式冲突 |
| ✅ 预处理器支持 | Sass/Less/Stylus 自由选择 |
| ✅ TypeScript 支持 | <script lang="ts"> 提供类型检查 |
SFC 是现代 Vue 开发的事实标准。
五、SFC 最佳实践
1. 组件命名规范
- 文件名:
PascalCase或kebab-caseUserProfile.vue或user-profile.vue
- 组件名:在
script中定义name属性
export default {
name: 'UserProfile'
}
✅ 有助于调试和性能分析。
2. 使用 <script setup>(Vue 3)
<script setup>
// 无需 return,直接在 template 中使用
const msg = ref('Hello')
</script>
✅ 更少的样板代码,更好的性能。
3. 合理使用 scoped 和 CSS Modules
- 一般用
scoped - 复杂样式隔离用
module
4. 逻辑复用:composables
将可复用逻辑抽离为 composables:
// composables/useCounter.js
export function useCounter() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
<script setup>
import { useCounter } from '@/composables/useCounter'
const { count, increment } = useCounter()
</script>
✅ 类似 React Hooks,提升逻辑复用性。
5. 避免过度嵌套
{{ message }}
{{ message }}
✅ 减少不必要的 DOM 层级。
六、SFC 与非 SFC 对比
| 特性 | SFC(.vue) | 非 SFC(JS/HTML) |
|---|---|---|
| 文件结构 | 集中式 | 分散式 |
| 构建工具 | 需要 | 不需要 |
| 开发体验 | 极佳 | 一般 |
| 样式作用域 | 支持 | 需手动处理 |
| TypeScript | 原生支持 | 支持差 |
| 适用场景 | 现代项目 | 嵌入式、原型 |
✅ SFC 是大型项目的唯一选择。
七、总结
| 核心点 | 说明 |
|---|---|
| 结构 | <template> + <script> + <style> |
| 优势 | 高内聚、可维护、工具友好、HMR |
| 编译 | 构建时编译为 JS 模块 |
| 推荐 | Vue 3 中使用 <script setup> |
| 最佳实践 | 命名规范、逻辑抽离、合理使用 scoped |
SFC 不仅是一种文件格式,更是一种工程化思想:将组件视为一个独立、可复用、自包含的单元。
八、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

浙公网安备 33010602011771号