news 2026/6/4 16:03:00

【Vue】认识单文件组件与模板语法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Vue】认识单文件组件与模板语法

目录

      • 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随用户操作而变化(比如点击按钮后改变文字),就需要用到refreactive。现在我们主要使用它来定义普通变量和函数,用于简单的静态展示或事件触发。


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>

注意:多根节点在某些边界情况下会有一些小问题(比如父组件向子组件传递classstyle时,不知道应该加到哪个根节点上)。但现在我们暂时不需要纠结这些,只需知道 Vue 3 支持多根节点即可。


以上三个知识点(<script setup><style scoped>、多根节点)构成了.vue文件的基本骨架。接下来,我们要学习在模板中动态控制元素的属性和行为。

4.v-bind(简写:) —— 动态绑定 HTML 属性

它是做什么的?
把 Vue 的数据(变量、表达式)绑定到 HTML 标签的属性上。常见的属性包括:srchrefclassstyledisabledalt等。普通情况下,这些属性是写死的(比如<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表示同时阻止冒泡和默认行为。


总结

  1. 我们先学习了.vue文件的三个组成部分:逻辑<script setup>)、样式<style scoped>)、模板(支持多根节点)。
  2. 在模板中,为了让页面“活”起来,我们需要根据数据动态控制 HTML 属性 → 使用v-bind:
  3. 同时,还需要响应用户的操作(点击、键盘等)→ 使用v-on@绑定事件,并用修饰符简化常见操作。
  4. 至此,我们已经能够写出一个具有基本交互能力的 Vue 组件了。

练习:点击按钮改变文字颜色或字体大小

要求
创建一个 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就是单位,如果不加上浏览器就识别不出来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 16:00:11

RTAB-Map:从传感器融合到空间智能的SLAM技术演进之路

RTAB-Map&#xff1a;从传感器融合到空间智能的SLAM技术演进之路 【免费下载链接】rtabmap RTAB-Map library and standalone application 项目地址: https://gitcode.com/gh_mirrors/rt/rtabmap 当机器人需要在未知环境中自主导航时&#xff0c;它面临着一个经典的技术…

作者头像 李华
网站建设 2026/6/4 15:58:55

GPT-5.5是真是假?AI模型版本识别与技术谣言辨析指南

我无法按照该标题生成符合事实与规范的博文内容。原因如下&#xff1a;GPT-5.5 并不存在&#xff1a;截至当前&#xff08;2024年&#xff09;&#xff0c;OpenAI 官方从未发布、命名或确认过 GPT-5、GPT-5.4 或 GPT-5.5 任何版本。其公开发布的最新通用大模型为 GPT-4&#xf…

作者头像 李华
网站建设 2026/6/4 15:56:50

告别桌面混乱:3步用NoFences打造高效工作空间

告别桌面混乱&#xff1a;3步用NoFences打造高效工作空间 【免费下载链接】NoFences &#x1f6a7; Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 你是否也曾面对满屏杂乱的桌面图标&#xff0c;花费宝贵时间寻找需要…

作者头像 李华
网站建设 2026/6/4 15:56:49

Kafka Exporter:5分钟搭建企业级Kafka监控体系,告别数据黑洞

Kafka Exporter&#xff1a;5分钟搭建企业级Kafka监控体系&#xff0c;告别数据黑洞 【免费下载链接】kafka_exporter Kafka exporter for Prometheus 项目地址: https://gitcode.com/gh_mirrors/ka/kafka_exporter 你是否曾经在深夜被Kafka报警吵醒&#xff0c;却不知道…

作者头像 李华
网站建设 2026/6/4 15:56:49

幻兽帕鲁存档修复终极指南:5步解决服务器迁移GUID冲突问题

幻兽帕鲁存档修复终极指南&#xff1a;5步解决服务器迁移GUID冲突问题 【免费下载链接】palworld-host-save-fix Fixes the bug which forces a player to create a new character when they already have a save. Useful for migrating maps from co-op to dedicated servers …

作者头像 李华