1431 字
7 分钟
Vue 3 模板语法与内置指令

模板插值#

双大括号(Mustache)把组件数据渲染成文本,是模板里最基础的取值方式。

<div>{{ message }}</div>

括号里只能放一个表达式。三元运算、算术、方法调用都有返回值,可以写;if、for、var 这类语句没有返回值,写进去会在编译时报错。

<div>{{ message === 0 ? '是' : '否' }}</div>
<div>{{ count + 1 }}</div>
<div>{{ text.split(',') }}</div>

插值默认转义 HTML,数据里的标签会原样显示,所以不能拿它渲染富文本。表达式依赖的数据变化后,这块内容自动更新。

数据要来自响应式状态#

模板读的是组件的响应式状态。普通变量后续变化不会触发更新,用 ref 或 reactive 包装过的才会。

const message = 'xxx' // 普通变量,改了视图不动
const msg = ref('xxx') // 响应式,改了视图更新

Vue 3 的响应式建立在 Proxy 上,只有被代理的数据会被追踪,模板才会跟着更新。

v- 开头的是指令#

v- 前缀只说明这是一个指令,不代表它是 Vue 内置的。需要别的行为时,用 app.directive() 注册自定义指令,名字同样以 v- 开头。

内置指令共 13 组,逐个见下文小节。

v-text#

给元素设置文本内容,效果上相当于把 {{ text }} 写在元素里面。

它写入的是 textContent,并且会覆盖元素里已有的全部内容,不解析 HTML。

v-html#

把字符串当 HTML 解析后渲染,用来显示富文本片段。

v-if 条件渲染#

v-if 为真才渲染里面的内容,为假时这些节点不在页面里,是真正的条件渲染。

v-else-if 和 v-else 必须紧跟在 v-if 后面,中间不能插入其他元素。

切换时要销毁和重建节点,成本比 v-show 高。

v-show#

v-show 只切 CSS。隐藏时给元素设 display: none,显示时恢复它原本的 display 值,这个值可能是 flex、inline,不一定是 block。

元素始终留在 DOM 里,初次渲染无论条件真假都会创建。

v-on 事件绑定#

v-on 绑定事件监听,简写是 @,v-on:click 和 @click 等价。

事件对象由 Vue 自动传入,修饰符作用在原生 event 上:.stop 调用 event.stopPropagation(),.prevent 调用 event.preventDefault()。

可用的修饰符有:

  • .stop:阻止事件冒泡
  • .prevent:阻止默认行为
  • .capture:改用捕获模式监听
  • .self:只在事件从元素本身触发时响应
  • .{keyAlias}:限定按键,如 @keyup.enter
  • .once:最多触发一次
  • .left、.right、.middle:限定鼠标按键
  • .passive:对应 addEventListener 的 passive: true

Vue 3 移除了 .native 修饰符;组件没有声明对应事件时,写在组件上的监听会作为透传 attribute 落到根元素。

v-bind 属性绑定#

v-bind 把表达式的值绑到属性上,简写是 :,v-bind:src 和 :src 等价,src、href、class、style 都能绑。

属性值整体是一段 JavaScript 表达式。属性值里出现引号、=、< 这类字符时,外面那层引号不能省。

v-bind 有三个修饰符:.camel 把短横线属性名转成驼峰,.prop 强制按 DOM property 绑定,.attr 强制按 attribute 绑定。

class 的写法#

数组写法把几个类名拼起来,元素里可以放条件表达式:

<div :class="[a ? 'c1' : 'c2', 'c3']"></div>

对象写法按键的值决定类名是否生效:

<div :class="{ c1: a, c2: b }"></div>

style 的写法#

对象写法最常用,也可以一次绑多个样式:

<div :style="{ color: 'red', fontSize: '14px' }"></div>

v-model 双向绑定#

v-model 在表单控件上双向同步:视图改数据,数据改视图。

它绑定的属性和监听的事件随元素类型变化:

元素绑定监听
文本类 <input type="text">、<textarea>valueinput
<input type="checkbox">、<input type="radio">checkedchange
<select>valuechange
组件modelValue propupdate:modelValue 事件

在组件上带参数时,参数替换名字:v-model:title 展开成 title prop 加 update:title 事件。

v-model 的修饰符有三个:.lazy 改成监听 change 事件;.number 用 parseFloat 解析输入值,type="number" 时自动启用;.trim 去掉首尾空白。

v-for 列表渲染#

v-for 遍历数组、对象或数字,每一项渲染一个块或组件。

<div v-for="(item, index) in items" :key="item.id">{{ item.name }}</div>

key 建议加上,但不强制:只要可能就加;如果这段列表的输出不依赖子组件状态或临时 DOM 状态,也可以省略。

加 key 时它只能是 number、string 或 symbol,必须在兄弟节点之间唯一,不能是对象。

v-slot#

v-slot 声明具名插槽和作用域插槽,简写是 #,v-slot:header 和 #header 等价。

它能写在 <template> 上,也能写在组件上,写在组件上时只支持单个默认作用域插槽。

v-pre#

v-pre 让 Vue 跳过这个元素和它全部子节点的编译,里面的 {{ }} 原样显示,适合用来展示模板语法的例子。

v-once#

v-once 只渲染一次。之后依赖的数据再变化,这块内容也不再更新,适合确定不会变的部分。

v-memo#

v-memo 是 3.2 新增的指令,接收一个数组(any[])。数组里的值都不变时,跳过这个元素和它子树的更新。

<div v-for="item in items" :key="item.id" v-memo="[item.id === selected]">
<p>{{ item.name }}</p>
</div>

传空数组 v-memo="[]" 等价于 v-once。它必须和 v-for 写在同一个元素上,写在 v-for 里面不生效。

v-cloak#

v-cloak 只在没有构建步骤的页面里用得上:模板还没编译时,浏览器会先显示原始的 {{ }}。给元素加上 v-cloak,再用一条样式把它藏起来,编译完成后 Vue 会移除这个属性。

[v-cloak] {
display: none;
}

第 10 篇,共 19 篇本文属于系列

Vue 3 模板语法与内置指令
https://www.choria.top/posts/vue3-template/
作者
乔瑞雅·克林威尔
发布于
2026-04-08
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

最后更新于 ,距今已过 214 天

部分内容可能已过时