目录
-
-
- 1. `<script setup>` —— 逻辑的“自动暴露”入口
- 2. `<style scoped>` —— 样式的“局部隔离罩”
- 3. 多根节点 —— 模板不再需要“一个根”
- 4. `v-bind`(简写 `:`) —— 动态绑定 HTML 属性
- 5. `v-on`(简写 `@`)+ 修饰符 —— 事件绑定与便捷操作
- 总结
- 练习:点击按钮改变文字颜色或字体大小
-
单文件组件(Single-File Component,简称 SFC)就是以一个 .vue 文件结尾的文件。这个文件把 HTML、JavaScript、CSS 三个部分写在一起,用来描述一个独立的、可复用的 UI 部件(比如一个按钮、一张卡片、一个输入框,甚至整个页面)。
一个Vue单文件组件的标准结构如下:
<template>
<!– 放 HTML 结构 –>
</template>
<script setup>
// 放 JavaScript 逻辑(数据、函数等)
</script>
<style scoped>
/* 放 CSS 样式 */
</style>
接下来,我们逐一拆解这三个部分以及相关的核心语法。
1. <script setup> —— 逻辑的“自动暴露”入口
它是做什么的? <script setup> 是 Vue 3 中一种更简洁的写法,用来写组件的 JavaScript 逻辑。你可以在里面定义 变量、函数、导入其他组件或工具。重点在于:所有定义在顶层的东西,都会自动被 <template> 使用,不需要像 Vue 2 那样手动 return。
有什么用? 让你写代码更简单、更直观。例如,你想在页面上显示一段文字,并绑定一个点击事件,可以这样写:
<template>
<h1>{{ message }}</h1>
<button @click="showAlert">点我</button>
</template>
<script setup>
// 普通变量(非响应式,适合静态展示)
const message = '你好,Vue 3!'
// 普通函数
function showAlert() {
alert('按钮被点击了')
}
</script>
这里要说明,{{ }} 是 Vue 模板中的 插值语法。它的作用是把 JavaScript 表达式的值直接显示到页面上。
注意:如果后续需要让 message 随用户操作而变化(比如点击按钮后改变文字),就需要用到 ref 或 reactive。现在我们主要使用它来定义普通变量和函数,用于简单的静态展示或事件触发。
2. <style scoped> —— 样式的“局部隔离罩”
它是做什么的? 给 <style> 标签加上 scoped 属性,表示这个样式 只对当前组件的模板生效,不会影响到其他组件。Vue 在编译时会自动给当前组件的 HTML 元素添加一个唯一的属性(比如 data-v-7ba5bd90),然后重写你的 CSS 选择器,使其只匹配带有该属性的元素。
有什么用? 防止样式冲突。在一个大项目中,很可能多个组件里都有类名 .title 或 .box,如果不加 scoped,后面引入的样式会覆盖前面的,导致样式错乱。使用 scoped 后,每个组件的样式都是独立的,互不干扰。
示例:
<!– 组件 A –>
<template>
<div class="box">组件 A 的盒子</div>
</template>
<style scoped>
.box { background-color: red; }
</style>
<!– 组件 B –>
<template>
<div class="box">组件 B 的盒子</div>
</template>
<style scoped>
.box { background-color: blue; }
</style>
渲染后,组件 A 的盒子背景是红色,组件 B 的盒子背景是蓝色,互不影响。
注意:如果需要让父组件的样式影响子组件内部的元素(比如想统一设置所有按钮的样式),可以用 :deep() 选择器,但这属于进阶用法,先了解 scoped 的作用即可。
3. 多根节点 —— 模板不再需要“一个根”
它是做什么的? 在 Vue 2 中,每个组件的 <template> 里必须有一个唯一的根元素(通常用一个 <div> 包裹所有内容)。Vue 3 移除了这个限制,你可以直接写多个并列的顶层元素。
有什么用? 减少不必要的包裹元素,让生成的 HTML 结构更干净。例如,一个组件要输出一个标题 + 一段描述 + 一个按钮,以前必须这样:
<!– Vue 2 写法 –>
<template>
<div>
<h1>标题</h1>
<p>描述文字</p>
<button>按钮</button>
</div>
</template>
现在 Vue 3 可以这样:
<!– Vue 3 写法 –>
<template>
<h1>标题</h1>
<p>描述文字</p>
<button>按钮</button>
</template>
注意:多根节点在某些边界情况下会有一些小问题(比如父组件向子组件传递 class 或 style 时,不知道应该加到哪个根节点上)。但现在我们暂时不需要纠结这些,只需知道 Vue 3 支持多根节点即可。
以上三个知识点(<script setup>、<style scoped>、多根节点)构成了 .vue 文件的基本骨架。接下来,我们要学习在模板中动态控制元素的属性和行为。
4. v-bind(简写 :) —— 动态绑定 HTML 属性
它是做什么的? 把 Vue 的数据(变量、表达式)绑定到 HTML 标签的属性上。常见的属性包括:src、href、class、style、disabled、alt 等。普通情况下,这些属性是写死的(比如 <img src="/logo.png">),但使用 v-bind 后,属性值可以动态变化。
有什么用? 让页面可以根据数据状态自动调整元素的样式或行为。比如:
- 根据条件给某个按钮添加 disabled 属性。
- 根据图片 ID 动态生成图片 URL。
- 根据某个布尔值切换 CSS 类名。
基本用法:
<template>
<!– 绑定图片地址 –>
<img :src="imageUrl" alt="动态图片">
<!– 绑定 disabled 属性 –>
<button :disabled="isDisabled">提交</button>
<!– 绑定 class(对象语法:键是类名,值是布尔值) –>
<div :class="{ active: isActive, 'text-bold': isBold }">动态类</div>
<!– 绑定 class(数组语法) –>
<div :class="['base', isActive ? 'active' : '']">数组方式</div>
<!– 绑定 style(对象语法) –>
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">动态样式</div>
</template>
<script setup>
const imageUrl = 'https://picsum.photos/200/150'
const isDisabled = true
const isActive = true
const isBold = false
const textColor = 'red'
const fontSize = 20
</script>
注意:v-bind: 可以简写为 :,这是最常用的写法。另外,class 和 style 的增强写法在实际开发中使用频率极高,一定要熟练。
: 的本质是:把属性从“静态字符串”变成“动态响应式绑定”,让属性值能够跟随数据变化。这就是它与普通 HTML 写法的根本区别。 也就是会把属性等号后面的引号里的内容被当作 JavaScript 代码来执行,而不是纯文本。
5. v-on(简写 @)+ 修饰符 —— 事件绑定与便捷操作
它是做什么的? 监听 DOM 事件(如点击、键盘输入、鼠标移动等),在事件发生时执行指定的 JavaScript 函数。
有什么用? 实现用户交互。比如按钮点击后提交表单、输入框按下回车后搜索、鼠标移入时显示提示等。
基本用法:
<template>
<button @click="handleClick">点我</button>
</template>
<script setup>
function handleClick(event) {
console.log('点击了', event.target)
}
</script>
事件修饰符:这是 Vue 提供的一组便捷语法,用来处理常见的事件细节,例如阻止冒泡、阻止默认行为、只在特定按键时触发等。它们以 . 加后缀的形式写在事件名后面。
| .stop | 阻止事件冒泡(不再触发父元素的事件) | @click.stop |
| .prevent | 阻止默认行为(如 <form> 提交刷新页面) | @submit.prevent |
| .enter | 只在回车键触发(用于 @keyup) | @keyup.enter |
| .once | 事件只触发一次 | @click.once |
| .self | 只有 event.target 是当前元素时才触发 | @click.self |
组合使用示例:
<template>
<!– 阻止冒泡 + 阻止默认行为 –>
<form @submit.prevent.stop="onSubmit">
<input type="text" />
<button type="submit">提交(页面不刷新,且不冒泡)</button>
</form>
<!– 按回车触发搜索 –>
<input @keyup.enter="search" placeholder="输入后按回车" />
<!– 只触发一次 –>
<button @click.once="onceClick">仅生效一次</button>
</template>
<script setup>
const onSubmit = () => console.log('表单提交了')
const search = (e) => console.log('搜索:', e.target.value)
const onceClick = () => alert('只能点出一次')
</script>
注意:修饰符可以串联,比如 @click.stop.prevent 表示同时阻止冒泡和默认行为。
总结
练习:点击按钮改变文字颜色或字体大小
要求: 创建一个 Vue 组件,包含一段文字和几个按钮。点击按钮可以改变文字的颜色或字体大小。
提示:
- 颜色和字体大小是动态变化的数据,需要使用 ref 来定义(这是阶段2的知识点,但请先按下面的方式照做,后续会系统学习)。
- 在 <script setup> 中:import { ref } from 'vue',然后用 const textColor = ref('red') 定义响应式数据,修改时用 textColor.value = 'blue',模板中直接写 textColor(不带 .value)。
- 字体大小同理:const fontSize = ref(16),修改时 fontSize.value += 4。
完整代码(可直接复制到 src/App.vue 中运行):
<template>
<div>
<!– 动态绑定颜色和字体大小 –>
<p :style="{ color: textColor, fontSize: fontSize + 'px' }" class="demo-text">
这是一段可变化的文字
</p>
<div class="button-group">
<button @click="textColor = 'red'">红色</button>
<button @click="textColor = 'green'">绿色</button>
<button @click="textColor = 'blue'">蓝色</button>
<button @click="fontSize += 2">放大字体</button>
<button @click="fontSize -= 2">缩小字体</button>
<button @click="reset">重置</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const textColor = ref('black')
const fontSize = ref(16)
function reset() {
textColor.value = 'black'
fontSize.value = 16
}
</script>
<style scoped>
.demo-text {
transition: all 0.2s;
margin-bottom: 16px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 6px;
}
.button-group button {
margin-right: 8px;
margin-bottom: 8px;
padding: 6px 12px;
cursor: pointer;
}
</style>
第一句代码中,:style加上的是内联样式,除非加上!important,它的优先级就是最高的。还有px就是单位,如果不加上浏览器就识别不出来。
![基于Vue的平潭岛特色旅游网站[Vue]-计算机毕业设计源码+LW文档-171主机测评](https://www.171host.com/wp-content/uploads/2026/10/20261029094837-6ae3167579222-220x150.jpg)

