模板语法与属性绑定
约 914 字大约 3 分钟
2026-01-02
概览
Vue 的模板语法基于 HTML,支持声明式地把状态映射到 DOM。模板会被编译为渲染函数,配合响应式依赖追踪,仅更新受影响的组件或节点。
插值与 HTML
文本插值
最基本的数据绑定形式是 Mustache 语法,使用 {{ }} 将数据插入到文本中。插值内容会被当作纯文本处理(自动转义)。
模板里不能在标签属性中使用双大括号,属性绑定需要 v-bind。
<template>
<div>{{ message }}</div>
</template>原始 HTML
使用 v-html 可以渲染原始 HTML,但内容不会再被 Vue 当作模板解析。
<template>
<div v-html="rawHtml"></div>
</template>注意
v-html 不会做安全过滤,禁止直接渲染用户输入内容,避免 XSS 风险。
属性绑定(v-bind)
v-bind 用于给属性绑定动态值;当绑定值为 null 或 undefined 时,对应属性会被移除。
<template>
<div v-bind:id="dynamicId"></div>
</template><template>
<div :id="dynamicId"></div>
</template><template>
<div :id></div>
</template>
<script setup>
const id = 'app'
</script>布尔属性
布尔类型属性(如 disabled)由是否存在来决定真假:绑定值为真值或空字符串时,属性存在;为假值时,属性被忽略。
<template>
<button :disabled="isButtonDisabled">Submit</button>
</template>Vue2 与 Vue3 的差异
Vue2 中 NaN 会被当作有效值保留布尔属性;Vue3 使用 Boolean(value) 判断,NaN 会被当作假值移除。
动态绑定多个属性
v-bind 可以直接绑定一个对象,常用于批量传参或拼装属性。
<template>
<div v-bind="attrs"></div>
</template>
<script setup lang="ts">
const attrs = {
id: 'wrapper',
class: 'wrapper-element'
}
</script>提示
class 与 style 会合并,其他同名属性后者覆盖前者。
表达式与方法调用
模板表达式支持完整的 JavaScript 单一表达式(不是语句),例如三元、模板字符串、逻辑运算。
<template>
<div>{{ number + 1 }}</div>
<div>{{ ok ? 'YES' : 'NO' }}</div>
<div :id="`list-${id}`"></div>
</template>可以在表达式中调用组件方法,但每次更新都会执行,因此必须保持纯函数、无副作用。
<template>
<time :title="toTitleDate(date)" :datetime="date">
{{ formatDate(date) }}
</time>
</template>提示
复杂逻辑建议放在 computed 或 methods 中,模板只负责展示。
模板沙盒化与全局对象
模板表达式运行在沙盒中,只能访问白名单内的全局对象。未在列表中的全局对象不可直接访问。
允许的全局对象(以当前版本源码为准)
const GLOBALS_ALLOWED = [
'Infinity',
'undefined',
'NaN',
'isFinite',
'isNaN',
'parseFloat',
'parseInt',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
'Math',
'Number',
'Date',
'Array',
'Object',
'Boolean',
'String',
'RegExp',
'Map',
'Set',
'JSON',
'Intl',
'BigInt',
'console',
'Error'
]需要扩展全局访问时,可通过 app.config.globalProperties 注入:
const app = createApp(App)
app.config.globalProperties.$filters = {
currency(value: number) {
return value.toFixed(2)
}
}在组合式 API 中获取实例后再访问:
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const filters = instance?.appContext.config.globalProperties.$filters类与样式绑定
class 与 style 支持字符串、对象、数组等形式,适合做条件化组合。
<template>
<div :class="className"></div>
<div :class="{ active: isActive, disabled: isDisabled }"></div>
<div :class="[baseClass, size, { active: isActive }]"></div>
</template><template>
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<div :style="[baseStyles, overrideStyles]"></div>
</template>模板编译与渲染流程
- 解析
template字符串,生成 AST - 基于 AST 做语法转换与优化(指令、表达式、静态提升等)
- 生成渲染函数(render function)
- 运行时执行渲染函数,产出 VNode 树
- Diff 新旧 VNode,按需更新真实 DOM
相关信息
虚拟 DOM 的 diff 能减少不必要的 DOM 操作,从而降低回流与重绘的成本。