# 模板语法

Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。
在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。

# 文本插值

最基本的数据绑定形式是文本插值,它使用的是 ”Mustache“ 语法(即双大括号):

    <span>Message: {{ msg }}</span>

双大括号标签会被替换为相应组件实例中 msg 属性的值。同时每次 msg 属性更改时它也会同步更新。

# 原始 HTMNL

双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令:

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

Using text interpolation: This should be red.

Using v-html directive: This should be red.

作用是:在当前组件实例上,将此元素的 innerHTML 与 rawHtml 属性保持同步。
span 标签中的内容会被替换为 rawHTML 属性的值,插入的值为纯 HTML— 数据绑定将被忽略。

注意:不能使用 v-html 来拼接组合模板。

# Attribute 绑定

双括号不能在 HTML attribute 中使用。想要响应式的绑定一个 attribute,应该使用 v-bind 指令。

  <div v-bind:id="dynamicId"></div>

v-bind 指令 指示 Vue 将元素的 id attribute 与组件的 dynamicId 属性保持一致。如果绑定的值是 null 或者 undefined,那么该 attribute 将从渲染的元素上移除。

# 简写

因为 v-bind 非常常用,提供了特定的简写语法

   <div :id="dynamicId"></div>

# 布尔型 attribute

布尔型依据 true/false 值来决定 attribute 是否应该存在于元素上。disabled 就是最常见的例子之一。

    <button :disabled="isButtonDisabled">Button</button>

isButtonDisabled 为真值,或者一个空字符串 (即 disabled=“”) 时,元素会包含这个 disabled attribute。而当其为其他假值时 attribute 将被忽略。

# 动态绑定多个值

如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:

    const objectOfAttrs = {
    id: 'container',
    class: 'wrapper'
    }

通过不带参数的 v-bind,你可以将它们绑定到单个元素上:

    <div v-bind="objectOfAttrs"></div>

# 使用 JavaScript 表达式

在 Vue 中,所有的数据绑定都支持完整的 JavaScript 表达式。

例如

  {{ number + 1 }}

  {{ ok ? 'YES' : 'NO' }}

  {{ message.split('').reverse().join('') }}

  <div :id="`list-${id}`"></div>

这些表达式都会被作为 JavaScript,以当前组件实例为作用域解析执行。

在 Vue 模板中,JavaScript 表达式可以使用在如下场景:

  1. 在文本插值中(双大括号)。
  2. 在任何 Vue 指令(以 v - 开头的特殊 attribute) attribute 的值中。

# 仅支持表达式

每个绑定仅支持单一表达式,也就是一段能够被求值的 JavaScript 代码。一个简单的判断方法是是否可以合法地写在 return 后面。

因此,下面的例子都是无效的:

    <!-- 这是一个语句,而非表达式 -->
  {{ var a = 1 }}

  <!-- 条件控制也不支持,请使用三元表达式 -->
  {{ if (ok) { return message } }}

# 调用函数

可以在绑定的表达式中使用一个组件暴露的方法。

  <span :title="toTitleDate(date)">
    {{ formatDate(date) }}
  </span>

# 受限的全局访问

模板中的表达式将被沙盒化,仅能够访问到有限的全局对象列表。该列表中会暴露常用的内置全局对象,比如 Math 和 Date。

没有显式包含在列表中的全局对象将不能在模板内表达式中访问,例如用户附加在 window 上的属性。然而,你也可以自行在 app.config.globalProperties 上显式地添加它们,供所有的 Vue 表达式使用。

# 指令 Directives

指令是带有 v- 前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的 v-bind 和 v-html。

指令 attribute 的期望值为一个 JavaScript 表达式 (除了少数几个例外,即之后要讨论到的 v-for、v-on 和 v-slot)。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。

以 v-if 为例

  <p v-if="seen">Now you see me</p>

# 参数 arguments

某些指令会需要一个 “参数”,在指令名后通过一个冒号隔开做标识。例如用 v-bind 指令来响应式地更新一个 HTML attribute:

  <a v-bind:href="url"> ... </a>

  <!-- 简写 -->
  <a :href="url"> ... </a>

另一个例子是 v-on 指令,它将监听 DOM 事件:

  <a v-on:click="doSomething"> ... </a>

  <!-- 简写 -->
  <a @click="doSomething"> ... </a>

# 动态参数

同样在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内:

  <!--
  注意,参数表达式有一些约束,
  参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
  -->
  <a v-bind:[attributeName]="url"> ... </a>

  <!-- 简写 -->
  <a :[attributeName]="url"> ... </a>

这里的 attributeName 会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。举例来说,如果你的组件实例有一个数据属性 attributeName,其值为 “href”,那么这个绑定就等价于 v-bind:href。

相似地,你还可以将一个函数绑定到动态的事件名称上:

  <a v-on:[eventName]="doSomething"> ... </a>

  <!-- 简写 -->
  <a @[eventName]="doSomething">

# 动态参数值的限制

动态参数中表达式的值应当是一个字符串,或者是 null。特殊值 null 意为显式移除该绑定。其他非字符串的值会触发警告。

# 动态参数语法的限制

动态参数表达式因为某些字符的缘故有一些语法限制,比如空格和引号,在 HTML attribute 名称中都是不合法的。例如下面的示例:

  <!-- 这会触发一个编译器警告 -->
  <a :['foo' + bar]="value"> ... </a>

如果你需要传入一个复杂的动态参数,我们推荐使用计算属性替换复杂的表达式,

当使用 DOM 内嵌模板(直接写在 HTML 文件里的模板)时,我们需要避免在名称中使用大写字母,因为浏览器会强制将其转换为小写:

  <a :[someAttr]="value"> ... </a>

上面例子将会在 DOM 内嵌模板中被转换为 ‘:[someattr]’ 。如果你的组件拥有属性 ‘someAttr’ 属性而非 ‘someattr’,那么这段代码将不会工作。单文件组件内的模板不受此限制

# 修饰符 MOdifiers

修饰符是以点开头的特殊后缀,表明指令需要一些特殊方式被绑定。例如 ‘.prevent’ 修饰符会告知 v-on 指令对触发的事件调用 event.preventDefault ():

  <form @submit.prevent="onSubmit">...</form>