人人都会AI编程

2.3 模板语法核心规则

更新时间:2026-07-09

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>

对于布尔类型的属性(如 disabledchecked),当表达式值为假时,属性甚至不会被渲染,这一点比原生 HTML 更合理。

class 与 style 的动态绑定

Vue 为 classstyle 提供了增强的绑定方式,因为这两个属性在 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 的指令。