Vue 的模板语法就像在写 HTML 的过程中,给元素增加了“感知数据”和“响应交互”的能力。你不用离开熟悉的标签语言,只需掌握几个核心规则,就能让界面活起来。
插值表达式 —— 让数据出现在页面上
最简单的数据绑定是 {{ }} 双大括号,它会将表达式的结果渲染为纯文本:
<span>当前用户:{{ username }}</span>
<p>{{ price * quantity }} 元</p>
大括号内可以写单一的 JavaScript 表达式(不能是语句或代码块),比如三元运算、方法调用、字符串拼接,Vue 会自动计算并更新结果。
指令体系 —— HTML 属性的“特殊能力”
指令是以 v- 开头的特殊属性,它们的值是一个表达式,会在表达式变化时对 DOM 元素施加某种影响。最基础的三个指令:
- v-bind:动态绑定属性。简写为
:。 - v-on:监听 DOM 事件。简写为
@。 - v-model:在表单元素上创建双向数据绑定。
<!-- 绑定 href 属性 -->
<a :href="url">前往</a>
<!-- 动态绑定 disabled 状态 -->
<button :disabled="isLoading">提交</button>
<!-- 绑定多个属性 -->
<div v-bind="{ id: 'card', title: '详情' }"></div>
对于布尔类型的属性(如 disabled、checked),当表达式值为假时,属性甚至不会被渲染,这一点比原生 HTML 更合理。
class 与 style 的动态绑定
Vue 为 class 和 style 提供了增强的绑定方式,因为这两个属性在 UI 开发中太常变化了。你可以传对象、数组甚至数组和对象的任意组合,Vue 会自动计算最终的 class 字符串或 style 对象。
<!-- 对象语法:根据 isActive 决定是否有 active 类 -->
<div :class="{ active: isActive, 'text-danger': hasError }"></div>
<!-- 数组语法:动态拼接类名 -->
<div :class="[baseClass, isActive ? 'active' : '']"></div>
<!-- style 绑定,驼峰或短横线命名均可 -->
<div :style="{ color: textColor, fontSize: size + 'px' }"></div>
这种写法让你完全告别了手动拼接 class="xxx " + (isActive ? 'active' : '') 的麻烦。
事件绑定与修饰符
用 v-on 或其简写 @ 可以绑定任何原生 DOM 事件,甚至自定义组件的自定义事件:
<button @click="handleClick">点击</button>
<form @submit.prevent="onSubmit">...</form>
事件修饰符是 Vue 特别贴心的地方,它们用点号连接在事件名后,帮你简化常见的 DOM 事件细节:
.prevent:调用event.preventDefault().stop:调用event.stopPropagation().once:事件只触发一次.self:只在event.target是自身时触发(非子元素冒泡).capture:使用捕获模式
<!-- 阻止表单默认提交,阻止冒泡,只触发一次 -->
<form @submit.prevent.stop.once="save">保存</form>
按键修饰符让你在处理键盘事件时,不用自己在方法里判断 event.key:
<input @keyup.enter="search" />
<button @keyup.esc="close">取消</button>
常用的按键别名有 .enter、.esc、.space、.delete 等,系统修饰符如 .ctrl、.shift、.meta 也可以配合使用,还能通过 .exact 控制精确组合。
一个综合示例
下面是一个简单的任务输入框,它展示了插值、指令、事件和 class 绑定的同时使用:
<template>
<div>
<input
v-model="newTask"
@keyup.enter="addTask"
placeholder="输入新任务"
/>
<ul>
<li
v-for="task in tasks"
:key="task.id"
:class="{ done: task.completed }"
@click="task.completed = !task.completed"
>
{{ task.text }}
</li>
</ul>
<p v-if="tasks.length === 0">暂无任务</p>
<span>共 {{ tasks.length }} 项</span>
</div>
</template>
<script setup>
import { ref } from 'vue'
const newTask = ref('')
const tasks = ref([
{ id: 1, text: '学习Vue模板语法', completed: false }
])
function addTask() {
if (newTask.value.trim()) {
tasks.value.push({
id: Date.now(),
text: newTask.value,
completed: false
})
newTask.value = ''
}
}
</script>
这套规则看起来多,但真正日常写起来只会用到几个组合。核心心法只有一条:你想让什么变,就在它对应的属性和事件上加上 Vue 的指令。