Vue.js: 模板语法

最后更新:2026-10-20

Vue 的模板语法是声明式的 HTML 扩展——在普通 HTML 之上加了一些"指令"和"插值",让你能把数据渲染到 DOM 上。整个模板语法和 HTML 90% 相似,学过 HTML 的人 30 分钟就能上手。

Vue 模板的核心是 3 个动作:插值(显示数据)+ 指令(绑定属性/事件)+ 表达式(运行 JS)。本课带你掌握这 3 个动作的标准写法。

相关指令:v-text v-html v-once

1. 你将学到


2. 一个电商商品卡片的渲染需求

(1) 痛点:30 个商品,复制粘贴 30 次?

Alice 正在构建一个电商后台。她需要展示 30 个商品卡片。最初的做法:

HTML
<!-- 复制粘贴 30 次,噩梦... -->
<div class="product-card">
  <h3>iPhone 15 Pro</h3>
  <p>Price: $999</p>
  <button>Edit</button>
</div>
<div class="product-card">
  <h3>MacBook Pro</h3>
  <p>Price: $2499</p>
  <button>Edit</button>
</div>
<!-- ... 还有 28 个 ... -->

产品经理 Charlie 说"把价格格式改成带货币符号":

"Alice,你不可能手动改 30 个文件。下个月要是 5,000 个商品呢?我们需要动态模板。"

(2) Vue 模板解法:1 个组件,30 个数据

5 行模板代码 × 30 个商品 = 0 复制粘贴。当产品名/价格变化时,Vue 自动更新 DOM。

(3) 收益

使用 Vue 模板后:


3. 插值:Mustache {{ }}

(1) 4 种插值写法

写法 效果 示例
{{ var }} 显示变量值 <p>{{ username }}</p> → Alice
{{ expr }} 显示 JS 表达式结果 <p>{{ count + 1 }}</p> → 6
{{ fn() }} 调用函数返回值 <p>{{ formatDate(date) }}</p> → 2026-07-02
{{ obj.prop }} 访问对象属性 <p>{{ user.name }}</p> → Alice

(2) 插值 5 大特性

(3) 插值 vs v-text 区别

▶ 示例:多种插值写法

▶ 试一试

输出:

TEXT
变量: Alice
表达式: 11
Passed (≥60)                 ← score=75,只渲染这一行,Failed 行不出现
日期: 2026-10-18             ← 按运行当天日期输出 YYYY-MM-DD
用户: Alice

(4) 📊 模板 vs HTML 速查

元素 HTML 写法 Vue 写法 说明
静态文本 <p>Hello</p> <p>{{ msg }}</p> 改动态
静态属性 <img src="x.jpg"> <img :src="url"> 改动态
静态 class <div class="box"> <div :class="cls"> 改动态
静态 style <div style="color: red"> <div :style="sty"> 改动态
点击事件 <button onclick="fn()"> <button @click="fn"> 改 Vue
条件渲染 无 <div v-if="ok"> Vue 独有
列表渲染 无 <div v-for="i in list"> Vue 独有

4. 文本指令:v-text / v-html / v-once

(1) 三指令对比

指令 作用 场景 安全性
{{ }} 插值 文本插值 默认首选 ✅ 安全
v-text 设置元素 textContent 替代插值的指令写法 ✅ 安全
v-html 设置元素 innerHTML 渲染富文本(慎用) ⚠️ XSS 风险
v-once 只渲染一次,后续不更新 静态优化 ✅ 安全

(2) v-html 警告

(3) v-once 性能优化


5. 属性绑定:v-bind 与缩写 :

(1) v-bind 基础

(2) class 与 style 绑定(重点)

(3) style 绑定

▶ 示例:5 种 v-bind 写法

▶ 试一试

输出:

TEXT
1. 基础: [50px 占位图]
2. 动态属性: [50px 占位图]        ← 同一张图,动态属性名为 alt,值为 Logo
3. 对象语法: A                   ← span 带 class="active"
4. 数组语法: B                   ← span 带 class="active error"
5. 字符串拼接: Profile           ← 链接指向 https://example.com/users/1001

6. 事件绑定:v-on 与缩写 @

(1) v-on 基础

(2) 常用事件修饰符(9 个)

(3) 修饰符链

▶ 示例:5 种 v-on 写法

▶ 试一试

输出:

TEXT
1. Click                        ← 点击后控制台打印 clicked
2. + (count: 0)                 ← 每点一次数字 +1:count: 1 → count: 2
3. Delete Item A                ← 点击后控制台打印 delete 1 PointerEvent
4. Save (阻止冒泡+默认行为)      ← 点击后控制台打印 Save 按钮被点击
5. [Ctrl+Enter 提交 输入框]      ← 输入内容后按 Ctrl+Enter 打印 Ctrl+Enter 提交

7. 表达式限制(不能写语句)

(1) 模板表达式 vs JS 语句

(2) 表达式 vs 计算属性

场景 用表达式 用计算属性
简单计算(1-2 个运算符) ✅ ❌
复杂逻辑(多步、循环) ❌ ✅
需要缓存 ❌ ✅
需要传参数 ✅ ❌(用方法代替)

8. 边界指令:v-pre / v-cloak

(1) v-pre:跳过编译

场景:展示 Vue 模板语法本身(如教学、文档站)。

(2) v-cloak:编译前隐藏

场景:防止编译前用户看到 {{ message }} 闪烁。


9. 完整示例:动态商品卡片

▶ 示例:基础商品卡片

▶ 试一试

输出:

TEXT
iPhone 15 Pro
$999
Only 5 left          ← 徽章带 low-stock 类(黄色)
[Add to Cart]        ← 点击后控制台打印 Added iPhone 15 Pro,页面文本不变

10. 常见错误速查

前面 8 章讲完了插值、v-text/v-html、v-bind、v-on 和表达式限制。最后把这几个最容易踩的坑集中列出来,写模板遇到问题就回来对照。

(1) 📊 5 个常见错误

错误 现象 解决
忘记 .value 模板里写 {{ count }},JS 里写 count.value 模板自动解包,JS 需 .value
写 if/for 在 {{ }} 编译报错 用 v-if / v-for 指令
v-html XSS 用户输入 <script> 执行 用 DOMPurify 清理
内联函数未传 $event 拿不到 event 对象 @click="fn($event)" 显式传
修饰符顺序错 阻止冒泡失败 .stop 写在 .prevent 前(按需)

相关指令:v-text v-html v-once

❓ 常见问题

Q {{ }} 和 v-text 有什么区别?
A 效果一样,都是设置元素的 textContent。区别是 {{ }} 可以和静态文本混用(<p>Hi, {{ name }}</p>),v-text 必须独占整个元素(<p v-text="msg"></p>)。推荐用 {{ }},更灵活。
Q v-html 安全吗?
A 不安全。v-html 会把字符串作为 HTML 解析,恶意用户可以注入 <script> 攻击你的站点。除非你 100% 信任数据源(如自己写的 Markdown 渲染),否则用 {{ }} 插值或先 DOMPurify.sanitize() 清理。
Q v-on 修饰符链的执行顺序?
A 从左到右。例如 @click.stop.prevent 先 stopPropagation() 再 preventDefault()。
Q v-bind 可以缩写,v-on 也能吗?
A v-bind 缩写是 :(去掉 v-bind),v-on 缩写是 @(推荐用)。两个缩写都是 Vue 2 起就支持的官方写法,IDE 高亮和自动补全都支持。
Q 模板里能写 if/else 吗?
A 不能。模板表达式要求有返回值,if/for 是语句不是表达式。用 v-if / v-else-if / v-else 指令实现条件渲染。
Q v-bind 怎么动态切换多个 class?
A 用对象语法 :class="{ active: isActive, 'text-danger': hasError }"。或数组语法 :class="[activeClass, errorClass]"。两种可以混用::class="[isActive && 'active', { 'error': hasError }]"。
Q 怎么监听键盘 Ctrl+S?
A 用系统修饰符 @keyup.ctrl.s="save" 或 @keydown.ctrl.s.prevent="save"(加 .prevent 阻止浏览器默认保存对话框)。Vue 3 还支持精确修饰符 .exact,如 @click.ctrl.exact 要求只按 Ctrl 不能加其他键。

📖 小节


📝 作业

  1. 基础题(难度⭐) 写一个 Vue 3 组件,渲染一个用户卡片,包含:

    • 用户名(插值)
    • 头像(v-bind)
    • "Follow" 按钮(v-on)
    • 在线/离线状态(class 动态切换)

    数据用:用户对象 { name: 'Alice', avatar: 'alice.jpg', online: true }

  2. 进阶题(难度⭐⭐) 实现一个简单的 Todo 列表:

    • 输入框(v-model 暂不用,v-bind:value + @input 模拟)
    • 添加按钮(@click + 表达式)
    • 列表渲染(v-for,下一课学)
    • 每项有删除按钮(@click + 传参)

    数据:const todos = ref(['Learn Vue', 'Build app', 'Deploy'])

  3. 挑战题(难度⭐⭐⭐) 写一个完整的商品详情卡片组件,支持:

    1. 5 种商品状态徽章(在售/缺货/预售/促销/下架)
    2. 5 种状态对应不同 class 颜色(用对象语法批量绑定)
    3. 数量加减按钮(@click 累加/累减)
    4. 数量 ≥ 库存时禁用"加入购物车"按钮(:disabled 动态)
    5. 至少 3 个事件修饰符(@click.stop / @submit.prevent 等)
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏