模板语法
Vue 使用基于 HTML 的模板语法,允许您声明性地将渲染的 DOM 绑定到底层组件实例的数据。所有 Vue 模板都是语法有效的 HTML,可以被遵循规范的浏览器和 HTML 解析器解析。
在底层,Vue 将模板编译成高度优化的 JavaScript 代码。结合响应性系统,Vue 可以智能地确定需要重新渲染的最小组件数量,并在应用状态变化时执行最小的 DOM 操作。
如果您熟悉虚拟 DOM 概念并喜欢 JavaScript 的原始力量,您也可以直接 编写渲染函数 而不是模板,并提供可选的 JSX 支持。但请注意,它们不像模板那样享受相同的编译时优化级别。
文本插值
数据绑定最基本的形式是使用“Mustache”语法(双大括号)进行文本插值
template
<span>Message: {{ msg }}</span>
大括号标签将被替换为对应组件实例 的 msg 属性值。它也会在 msg 属性变化时更新。
原始 HTML
双大括号将数据解释为纯文本,而不是 HTML。为了输出真正的 HTML,您需要使用 v-html
指令
template
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
使用文本插值: <span style="color: red">This should be red.</span>
使用 v-html 指令: This should be red.
在这里我们遇到了一些新事物。您看到的 v-html
属性被称为一个 指令。指令以 v-
前缀开头,以表示它们是由 Vue 提供的特殊属性,正如您可能猜测的,它们会给渲染的 DOM 应用特殊的响应式行为。在这里,我们基本上是说“保持这个元素的内部 HTML 与当前活动实例上的 rawHtml
属性保持一致。”
span
的内容将被 rawHtml
属性的值替换,该值被解释为纯 HTML - 忽略数据绑定。请注意,您不能使用 v-html
来组合模板部分,因为 Vue 不是一个基于字符串的模板引擎。相反,组件是 UI 重用和组合的基本单元。
安全警告
在您的网站上动态渲染任意 HTML 可能非常危险,因为它很容易导致 XSS 漏洞。仅在有信任的内容时使用 v-html
,绝对不要 在用户提供的内用使用。
属性绑定
不能在 HTML 属性中使用花括号。相反,使用一个 v-bind
指令
template
<div v-bind:id="dynamicId"></div>
v-bind
指令指示 Vue 保持元素的 id
属性与组件的 dynamicId
属性同步。如果绑定值为 null
或 undefined
,则该属性将从渲染的元素中删除。
简写
因为 v-bind
非常常用,所以它有一个专门的简写语法
template
<div :id="dynamicId"></div>
以 :
开头的属性可能看起来与正常 HTML 有点不同,但实际上它是属性名中的一个有效字符,并且所有 Vue 支持的浏览器都可以正确解析它。此外,它们不会出现在最终的渲染标记中。简写语法是可选的,但您在以后学习其用法时可能会发现它很有用。
在本指南的其余部分,我们将使用简写语法在代码示例中,因为这是 Vue 开发者最常用的用法。
同名字段简写
- 仅在 3.4+ 版本中支持
如果属性名与正在绑定的 JavaScript 值同名,则语法可以进一步简化,以省略属性值
template
<!-- same as :id="id" -->
<div :id></div>
<!-- this also works -->
<div v-bind:id></div>
这与在 JavaScript 中声明对象时使用的属性简写语法类似。请注意,这是一个仅在 Vue 3.4 及以上版本中可用的功能。
布尔属性
布尔属性 是通过在元素上出现来表示真 / 假值的属性。例如,disabled
是最常用的布尔属性之一。
v-bind
在这种情况下的工作方式略有不同
template
<button :disabled="isButtonDisabled">Button</button>
如果 isButtonDisabled
有一个 真值,则将包含 disabled
属性。如果值是空字符串,它也将包含,以保持与 <button disabled="">
的一致性。对于其他 假值,将省略属性。
动态绑定多个属性
如果您有一个表示多个属性的 JavaScript 对象,看起来像这样
js
const objectOfAttrs = {
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}
您可以使用不带参数的 v-bind
将它们绑定到单个元素上
template
<div v-bind="objectOfAttrs"></div>
使用JavaScript表达式
到目前为止,我们只在我们的模板中绑定到简单的属性键。但实际上,Vue支持所有数据绑定中JavaScript表达式的全部功能
template
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
这些表达式将在当前组件实例的数据作用域中作为JavaScript进行评估。
在Vue模板中,JavaScript表达式可以在以下位置使用
- 在文本插值(花括号)内
- 在任何Vue指令的属性值中(以
v-
开头的特殊属性)
仅表达式
每个绑定只能包含一个单一的表达式。一个表达式是一段可以被评估为值的代码。一个简单的检查是看它是否可以在return
之后使用。
因此,以下将不会工作
template
<!-- this is a statement, not an expression: -->
{{ var a = 1 }}
<!-- flow control won't work either, use ternary expressions -->
{{ if (ok) { return message } }}
调用函数
在绑定表达式中调用组件暴露的方法是可能的
template
<time :title="toTitleDate(date)" :datetime="date">
{{ formatDate(date) }}
</time>
提示
在绑定表达式中调用的函数会在组件更新时被调用,因此它们不应该有任何副作用,比如改变数据或触发异步操作。
限制全局访问
模板表达式是沙箱化的,并且只有访问一个限制的全局变量列表。该列表公开了常用内置全局变量,如Math
和Date
。
不在列表中明确包含的全局变量,例如window
上的用户附加属性,在模板表达式中将不可访问。但是,您可以显式地为所有Vue表达式定义额外的全局变量,方法是将它们添加到app.config.globalProperties
。
指令
指令是具有v-
前缀的特殊属性。Vue提供了一些内置指令,包括我们上面介绍的v-html
和v-bind
。
指令属性值应期望是单个JavaScript表达式(除了v-for
、v-on
和v-slot
,这些将在后面的相应部分中讨论)。指令的职责是在其表达式的值更改时,有反应性地更新DOM。以v-if
为例
template
<p v-if="seen">Now you see me</p>
在这里,v-if
指令将根据表达式seen
的布尔值移除或插入<p>
元素。
参数
一些指令可以接受一个“参数”,由指令名称后的冒号表示。例如,v-bind
指令用于有反应性地更新HTML属性
template
<a v-bind:href="url"> ... </a>
<!-- shorthand -->
<a :href="url"> ... </a>
在这里,href
是参数,它告诉 v-bind
指令将元素的 href
属性绑定到表达式 url
的值。在简写形式中,参数之前的内容(即 v-bind:
)被压缩成一个字符 :
。
另一个例子是 v-on
指令,它监听 DOM 事件
template
<a v-on:click="doSomething"> ... </a>
<!-- shorthand -->
<a @click="doSomething"> ... </a>
在这里,参数是要监听的事件名称:click
。 v-on
有一个对应的简写形式,即 @
字符。我们还将更详细地讨论事件处理。
动态参数
通过使用方括号包围,也可以在指令参数中使用 JavaScript 表达式
template
<!--
Note that there are some constraints to the argument expression,
as explained in the "Dynamic Argument Value Constraints" and "Dynamic Argument Syntax Constraints" sections below.
-->
<a v-bind:[attributeName]="url"> ... </a>
<!-- shorthand -->
<a :[attributeName]="url"> ... </a>
在这里,attributeName
将作为一个 JavaScript 表达式动态求值,其求值后的结果将作为参数的最终值。例如,如果你的组件实例有一个数据属性,名为 attributeName
,其值为 "href"
,那么这个绑定将等同于 v-bind:href
。
同样,你可以使用动态参数来将处理程序绑定到动态事件名称
template
<a v-on:[eventName]="doSomething"> ... </a>
<!-- shorthand -->
<a @[eventName]="doSomething"> ... </a>
在这个例子中,当 eventName
的值为 "focus"
时,v-on:[eventName]
将等同于 v-on:focus
。
动态参数值约束
动态参数预期求值为一个字符串,除了 null
之外。特殊值 null
可以用来显式移除绑定。任何其他非字符串值都会触发警告。
动态参数语法约束
由于某些字符(如空格和引号)在 HTML 属性名称中是无效的,因此动态参数表达式有一些语法约束。例如,以下是不合法的
template
<!-- This will trigger a compiler warning. -->
<a :['foo' + bar]="value"> ... </a>
如果你需要传递一个复杂的动态参数,可能最好使用 计算属性,我们将在稍后介绍。
当使用 in-DOM 模板(直接在 HTML 文件中编写的模板)时,还应避免使用大写字母命名键,因为浏览器会将属性名称转换为小写
template
<a :[someAttr]="value"> ... </a>
上述内容在 in-DOM 模板中将被转换为 :[someattr]
。如果你的组件有 someAttr
属性而不是 someattr
,则你的代码将无法正常工作。单文件组件中的模板 不 受此约束。
修饰符
修饰符是特殊的后缀,由点表示,它表示指令应以某种特殊方式绑定。例如,.prevent
修饰符告诉 v-on
指令在触发的事件上调用 event.preventDefault()
。
template
<form @submit.prevent="onSubmit">...</form>
稍后你将看到其他修饰符的示例,当探索那些功能时,我们将讨论 v-on 和 v-model 的修饰符。
最后,这里是完整的指令语法的可视化表示