六维教程

Vue3 初识组件

进入 Vue3 后,最核心的概念就是组件。简单说,页面上的一个区域(导航栏、卡片、整个页面)都可以拆成一个组件,组件可以嵌套、复用。

Vue3 推荐用 SFC(单文件组件,Single File Component) 的写法,一个 .vue 文件就是一个组件,把模板、逻辑和样式集中在一起,方便阅读和复用。

下面我们打开项目自带的 src/App.vue 来看。

组件结构

项目里的 App.vue 大致是这种结构:

<template>
  <!-- ① 模板部分:编写页面结构(HTML 语法) -->
</template>

<script setup>
// ② 脚本部分:编写组件逻辑(JavaScript 语法)
</script>

<style>
/* ③ 样式部分:编写组件样式(CSS 语法) */
</style>
区块 作用 使用的语言
<template> 定义页面结构 HTML 语法
<script> 定义数据、方法和生命周期逻辑 JS / TS
<style> 定义组件样式,默认是全局,可加 scoped CSS

局部样式

<style> 默认是全局的;加上 scoped(写作 <style scoped>)后,样式只对当前组件生效,避免污染其他组件。

组件逻辑

Vue 的组件逻辑有两种写法:

  • 选项式 API(Options API):把数据、方法等放在不同的「选项」里分类组织的写法(会用到 datamethods 等关键词,偶尔在旧资料里见到)。
  • 组合式 API(Composition API):官方主推的写法,把逻辑按功能直接写在一起,更灵活,也是新项目的首选。

本教程采用 组合式 API,并统一使用它的语法糖 <script setup>,这种写法最简洁,也是新项目的首选。

你可能在老项目或网上资料里看到过 <script> 里写 setup(){} 并手动 return 的写法,两者背后是同一套概念,区别会在后面「常见疑问」里对比。

理论介绍完了,直接看例子。回到 App.vue,把 <template> 里换成变量,并在<script setup> 里声明它:

<script setup>
// 这里直接写 JavaScript,所有顶层变量自动暴露给模板使用
const msg = '你好,Vue3!'
</script>

<template>
  <p>{{ msg }}</p>
</template>

这就是一个能正常跑起来的”入门版组件”,两个地方要注意:

  • <script setup> 中的顶层变量、函数,模板可直接使用。
  • 模板里的 {{ }}插值表达式,会把变量值显示出来。

响应式

上面的 msg 是写死的文字,就算在脚本里改它的值,页面也不会跟着变,这就像静态页面。

Vue 的响应式是指「数据一变,用到它的地方自动跟着更新」。

但普通的 JS 变量变了,Vue 感知不到,所以要用 ref 把数据包一层,让 Vue 能追踪它的变化:

<script setup>
import { ref } from 'vue'

const count = ref(0)   // 响应式数据 count,初始值 0
</script>

<template>
  <p>点击数:{{ count }}</p>
</template>

ref 返回的是一个对象,真正的值藏在 count.value 里。

所以操作 count 时只要记住两条规则:

  1. 脚本中:读写都要写 .value,例如 count.value++
  2. 模板中:Vue 会自动解包,直接写 count 即可,不需要(也不能)写 .value

由此可以推出关键结论:脚本里改 count.value,模板中的 {{ count }} 就会自动刷新,显示的活交给模板,更新的活交给 Vue,脚本只管专心改数据。

到这里响应式就讲完了:脚本只负责改数据,显示和更新都交给 Vue。

至于「点击按钮怎么让数据变」,那属于事件处理,本篇先不展开,后面会有事件处理专门一篇讲解,这里先照着用即可。

组件示例

把上面学的整合起来,ref 存数据、{{ }} 显示、<style scoped> 管样式,就是一个完整的计数器组件 Counter.vue

<template>
  <div class="counter">
    <!-- @click 是事件绑定(点击执行 add / reset),属于事件处理,后面会专门讲 -->
    <p>当前值:{{ count }}</p>
    <button @click="add">+1</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)

const add = () => {
  count.value++
}

const reset = () => {
  count.value = 0
}
</script>

<style scoped>
.counter {
  border: 1px solid #ddd;
  padding: 16px;
  border-radius: 8px;
  text-align: center;
}
button {
  margin: 0 8px;
  padding: 4px 12px;
  cursor: pointer;
}
</style>

把这个组件在 App.vue 里导入使用,刷新页面(开发服务器会自动热更新)就能看到效果:

<script setup>
import Counter from './components/Counter.vue'
</script>

<template>
    <Counter />
  </template>

Counter 写好了,怎么把它用到页面里、组件之间怎么互相引用?规则很简单,看下一节。

组件引用

上面的计数器只是单个组件,一个页面往往由多个组件拼装而成。

其实上一节已经用过了引用的写法:在 <script setup>import 进来,模板里直接用组件名当标签——导入即用,不需要额外注册

而且组件可以复用,import 一次,模板里想放几个就放几个,比如在页面上同时放两个计数器:

<script setup>
import Counter from './components/Counter.vue'
</script>

<template>
  <Counter />
  <Counter />
</template>

至此,你已经知道一个组件的三部分代码分别怎么写、组件之间怎么引用。

常见疑问

<script setup><script> 区别

对比 <script>(选项式 / 手写 setup) <script setup>(组合式语法糖)
暴露数据 必须 return 自动暴露
注册组件 需在 components 选项里注册 导入即用
写法 相对繁琐 极简
适用场景 老项目维护 新项目首选

可以同时使用 <script setup> 和普通 <script> 吗?

可以,但极少需要,那是处理特殊需求(如设置组件 name)时用的。新手阶段统一用 <script setup> 即可,不用管它。

速查卡片

要点 写法
组件文件 .vue 文件(SFC)
结构 <template> + <script setup> + <style scoped>
引入子组件 import X from './X.vue'
定义响应式数据 const x = ref(初始值)
脚本中读写 x.value
模板中使用 直接写 x

掌握了这些,你已经能写出「自包含、可复用」的 Vue 组件了。

上一篇
Vue3 起步
下一篇
Vue3 模板基础