模板语法与指令
约 743 字大约 2 分钟
布欧-Lewyon
2026-05-15
Vue 的模板语法是声明式渲染的核心——在 HTML 中"声明"数据和 DOM 的关系。
插值:{{ }}
最基础的文本绑定:
<script setup>
const msg = 'Hello'
const html = '<strong>加粗</strong>'
const count = ref(42)
</script>
<template>
<p>{{ msg }}</p> <!-- Hello -->
<p>{{ msg.toUpperCase() }}</p> <!-- HELLO -->
<p>{{ count + 1 }}</p> <!-- 43 -->
<p>{{ html }}</p> <!-- <strong>加粗</strong>(作为文本) -->
</template>
{{ }}内可写任意单行 JavaScript 表达式(赋值语句、new操作符、控制流不行)。
v-html:渲染原始 HTML
<p v-html="html"></p> <!-- <strong>加粗</strong>(渲染为 HTML) -->安全提醒:
v-html会跳过 XSS 过滤,绝不要渲染用户输入的内容。
绑定属性:v-bind
简写 ::
<script setup>
const url = ref('https://vuejs.org')
const isActive = ref(true)
const styleObj = { color: 'red', fontSize: '14px' }
</script>
<template>
<!-- 标准写法 -->
<a v-bind:href="url">Vue</a>
<!-- 简写 -->
<a :href="url">Vue</a>
<!-- 动态参数 -->
<a :[attributeName]="url">Vue</a> <!-- attributeName = 'href' -->
<!-- class 绑定 -->
<div :class="{ active: isActive, disabled: !isActive }">Class 对象</div>
<div :class="['base', isActive ? 'active' : '']">Class 数组</div>
<!-- style 绑定 -->
<div :style="styleObj">Style 对象</div>
<div :style="{ color: 'red', fontSize: size + 'px' }">内联 Style</div>
<!-- 批量绑定对象 -->
<div v-bind="{ id: 'box', 'data-type': 'card' }"></div>
</template>事件绑定:v-on
简写 @:
<script setup>
const count = ref(0)
function handleClick(e) { count.value++ }
function handleInput(e) { console.log(e.target.value) }
</script>
<template>
<!-- 标准写法 -->
<button v-on:click="handleClick">+1</button>
<!-- 简写 -->
<button @click="handleClick">+1</button>
<!-- 内联表达式 -->
<button @click="count++">+1</button>
<!-- 传递原生事件对象 --> <!-- 等同于 disable > .prevent() -->
<form @submit.prevent="onSubmit">
<!-- 停止传播 -->
<div @click.stop="handleParentClick">
<button @click="handleChildClick">不会冒泡</button>
</div>
<!-- 按键修饰符 -->
<input @keyup.enter="submit" />
<input @keyup.ctrl.enter="submitWithCtrl" />
<!-- 事件修饰符链式 -->
<a @click.prevent.stop href="/">不会跳转也不会冒泡</a>
</template>事件修饰符
| 修饰符 | 作用 | 等价于 |
|---|---|---|
.stop | 阻止冒泡 | e.stopPropagation() |
.prevent | 阻止默认行为 | e.preventDefault() |
.self | 只有 e.target 是自身时才触发 | — |
.once | 只触发一次 | { once: true } |
.capture | 捕获阶段触发 | addEventListener 第三个参数 |
.passive | 不调用 preventDefault | 滚动性能优化 |
动态参数
参数本身可以是表达式:
<template>
<!-- 动态属性名 -->
<input :[attrName]="value" /> <!-- attrName = 'placeholder' -->
<!-- 动态事件名 -->
<button @[eventName]="handleClick" /> <!-- eventName = 'click' -->
<!-- 转义:参数值不能有空格/引号,需要计算 -->
<a :[`data-${key}`]="val"> </a>
</template>动态参数表达式必须求值为字符串,
null表示移除绑定。
v-bind 与 v-on 的对象语法
<template>
<!-- 批量绑定多个属性 -->
<div v-bind="{ id: 'app', class: 'main', 'data-test': 'true' }"></div>
<!-- 批量绑定多个事件 -->
<div v-on="{ click: handleClick, mouseenter: handleEnter }"></div>
</template>指令缩写一览
| 完整写法 | 缩写 |
|---|---|
v-bind:attr | :attr |
v-on:event | @event |
v-on:event.prevent | @event.prevent |
v-slot:name | #name |
小结
| 语法 | 关键点 |
|---|---|
{{ }} | 文本插值,纯文本,支持单行表达式 |
v-html | 渲染 HTML,⚠️ 小心 XSS |
v-bind (:) | 绑定属性/class/style |
v-on (@) | 绑定事件,@click.stop.prevent 链式修饰符 |
| 动态参数 | :[attrName] / @[eventName],值必须为字符串 |
上一节:Vue 概述与开发环境 下一节:Options API:响应式基础
