首页 / Nuxt 4 入门教程 / Vue 3 核心概念速览

Nuxt 4 入门教程

Vue 3 核心概念速览

本教程共 50 篇 · 第 10 篇 · 更新于 2026-08-08 · 约 7 分钟阅读

NuxtNuxt4Vue3SFC模板语法响应式

本节目标:在写 Nuxt 之前,先建立 Vue 3 的基本认知——单文件组件长什么样、模板语法怎么写、响应式思想到底是什么。

Nuxt 的页面和组件本质都是 Vue。不先看懂 Vue,后面写 Nuxt 会处处犯懵。这章不追求全面,只挑「用 Nuxt 必须知道」的那部分:组件结构、模板语法、响应式思想。后面的组合式 API、组件通信也都是建立在这之上。

10-1

Vue 把「界面 + 逻辑 + 样式」打包进一个 .vue 文件,叫单文件组件(SFC,Single File Component)。Nuxt 原生支持它,你写的每个页面、组件都是一个 SFC。

一个最简单的 SFC 由三部分组成:

<template>
  <p>你好,{{ name }}</p>
</template>

<script setup lang="ts">
const name = 'Nuxt'
</script>

<style scoped>
p { color: #333; }
</style>
  • <template>:写 HTML 结构,决定页面长什么样。
  • <script setup>:写 JavaScript/TypeScript 逻辑,驱动渲染。
  • <style>:写 CSS,可选;加 scoped 表示样式只作用于当前组件。
Tip

<script setup> 是官方推荐的写法,配合组合式 API 体验最好。Nuxt 还额外帮你自动导入 Vue 的工具(如 refcomputed),不用自己写 import。这是 Nuxt 和原生 Vue 一个很爽的区别。

三部分不必全有,但 <style> 不能单独存在(它得知道样式属于谁)。一般推荐顺序:先 <template> 看长相,再 <script> 看逻辑,最后 <style>

10-2

<template> 看起来像 HTML,但多了几个 Vue 专属写法,掌握这几个就够用:

1. 插值(Mustache 语法) 双花括号 {{ }} 里可以放变量或简单表达式,渲染时会被求值成纯文本:

<template>
  <p>{{ message }}</p>
  <p>价格:{{ price * 1.1 }}</p>
</template>
Note

模板里更适合放「简单引用或调用」。复杂的计算逻辑请挪到 <script> 里(比如用 computed),保持模板干净、好读。

2. 属性绑定 v-bind(简写 : 要把一个 JS 表达式绑到 HTML 属性上,用 :

<template>
  <img :src="logoUrl" :alt="logoText" />
</template>

3. 事件绑定 v-on(简写 @ 监听事件(点击、输入等),用 @

<template>
  <button @click="handleClick">点我</button>
</template>

4. 常用指令

  • v-if / v-else:条件成立才渲染该元素。
  • v-show:始终渲染,只是用 CSS 控制显隐。
  • v-for:遍历列表渲染多项。
  • v-html:插入 HTML 内容(有安全风险,慎用)。

一个综合例子:

<template>
  <ul>
    <li v-for="item in items" :key="item.id">{{ item.name }}</li>
  </ul>
  <p v-if="items.length === 0">列表是空的</p>
</template>

10-3

「响应式(reactivity)」是 Vue 最核心的思想,也是它和其他手动操作 DOM 的库最不同的地方。

直观理解:你声明一个数据,Vue 会「盯着」它。一旦它变了,所有用到它的地方(模板里的显示、依赖它的计算)自动更新,你完全不用手动去改 DOM

举个生活类比:响应式像一面「魔法镜子」。你对镜子前的人(数据)做了任何改动,镜子里(界面)立刻同步反映出来,不需要你跑去擦镜子、重画镜子。

在 Vue 3 里,响应式靠几个 API 实现:refreactivecomputedwatch。它们下一章详细讲,这里先看个感觉:

<script setup lang="ts">
// ref 把一个值包成「响应式的」
const count = ref(0)

function handleClick() {
  // 脚本里改值要加 .value
  count.value++
}
</script>

<template>
  <!-- 模板里直接用,不用 .value -->
  <p>计数:{{ count }}</p>
  <button @click="handleClick">加一</button>
</template>

点按钮,count 变了,模板里的显示自动跟着变。这就是响应式——你只管改数据,界面交给 Vue。

Warning

响应式只在「被 Vue 追踪的容器(如 ref)」里生效。如果你用一个普通变量 let count = 0,改了它界面也不会更新。初学最容易踩这个坑:记得用 ref/reactive 包起来。

10-4

Vue 并不直接操作浏览器真实 DOM,而是维护一个轻量的虚拟 DOM(Virtual DOM):一个用 JS 对象描述的界面结构。数据变化时,Vue 先在虚拟 DOM 上算出最小改动,再高效地更新真实 DOM。这也是为什么 Vue 性能好——它避免了频繁、大范围地操作真实页面。

组件之间天然形成一棵树:根组件 app.vue 在最上,页面、子组件层层嵌套。这种树状结构也是后面「props 向下传、事件向上冒」的通信基础(第 12 章讲)。

10-5

前面说 Vue 会「盯着」数据。它到底怎么盯的?Vue 3 靠的是 JavaScript 的 Proxy:当你用 ref/reactive 包住一个值时,Vue 给这个值套了一层「代理」。之后任何读取(比如模板里显示它)、任何修改(比如 count.value++),都会经过这层代理,Vue 趁机记下「谁在用这个值」以及「值变了要通知谁」。

这带来一个关键推论:只有经过代理的读写才被追踪。如果你在 <script> 里写 const x = count.value 把值取出来存进普通变量 xx 就和响应式脱钩了——之后再改 countx 不会跟着变。所以响应式数据要一直通过 ref/reactive 访问,别随便「拆」出来。

Warning

这也是为什么「在模板里直接 {{ count }}」能自动更新:模板的读取走的是代理通道,Vue 知道这个显示依赖于 count。而普通 let 变量根本没进代理,改了也没人通知界面。

10-6

ref 把值包进一个对象 { value: ... },是为了让「基本类型(数字、字符串)」也能被 Proxy 统一代理——因为 Proxy 只能代理对象,不能直接代理一个数字。reactive 能省掉 .value 是因为它代理的就是对象本身。

模板里自动 .value 是 Vue 编译器给的糖:它认得 ref,渲染时帮你补上。但脚本里是普通 JS 环境,编译器帮不上,所以你得自己写 count.value。记住这一条,初学八成的「值改了界面没动」都源于忘了 .value

Tip

记不住规则时,用一条笨办法:在 <script> 里看到 ref,一律点 .value;在 <template> 里看到 ref,一律不点。照做就不会出错。

10-7

Vue 3 的三个地基:SFC 把模板/逻辑/样式收进 .vue;模板用插值、v-bind、事件和指令把数据接到 HTML;响应式让你只改数据、界面自动更新。下一章我们正式学组合式 API,把 refcomputedwatch 用熟。

10-9 从 Vue 到 Nuxt 的思维转换

掌握 Vue 3 的核心概念后,进入 Nuxt 的学习会顺畅很多。Nuxt 并没有改变 Vue 的用法,它只是在 Vue 之上添加了框架级别的能力。你在 Vue 里写的 <script setup>、组合式 API、响应式数据,在 Nuxt 里完全一样。

唯一的区别在于”代码放在哪里”。纯 Vue 项目里,你需要手动配置路由、手动注册组件;Nuxt 把这些自动化了。你只需要把文件放到正确的目录,框架替你完成剩下的工作。这种”约定优于配置”的理念贯穿 Nuxt 的方方面面。

另一个需要适应的变化是服务端思维。纯前端项目只考虑浏览器环境,而 Nuxt 的代码可能在服务端执行。这意味着你不能在组件顶层直接访问 windowdocument 等浏览器 API,需要放到 onMounted 钩子里。这个思维转换是初学者最需要跨越的一步。