插值表达式

插值表达式是 Vue 模板中最基础的数据绑定方式,使用双大括号 {{ }} 包裹表达式,也被称为 Mustache 语法。

文本插值

最基本的形式是将数据绑定到文本:

<span>消息: {{ message }}</span>

<script>
new Vue({
  data: {
    message: 'Hello Vue!'
  }
})
</script>

Mustache 标签会被替换为 message 属性的值。当 message 改变时,页面会自动更新。

使用 JavaScript 表达式

Vue 支持在插值表达式中使用完整的 JavaScript 表达式:

<div id="app">
  <!-- 算术运算 -->
  <p>{{ number + 1 }}</p>
  
  <!-- 三元表达式 -->
  <p>{{ ok ? 'YES' : 'NO' }}</p>
  
  <!-- 字符串方法 -->
  <p>{{ message.split('').reverse().join('') }}</p>
  
  <!-- 调用方法 -->
  <p>{{ formatDate(date) }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    number: 10,
    ok: true,
    message: 'Hello',
    date: new Date()
  },
  methods: {
    formatDate: function(date) {
      return date.toLocaleDateString()
    }
  }
})
</script>

表达式的限制

只能使用表达式,不能使用语句

<!-- ✅ 正确:这是表达式 -->
{{ message.toUpperCase() }}

<!-- ❌ 错误:这是语句,不工作 -->
{{ var a = 1 }}

<!-- ❌ 错误:流程控制语句 -->
{{ if (ok) { return message } }}

表达式 vs 语句

  • 表达式:能返回一个值的代码,如 a + bfn()a ? b : c
  • 语句:执行操作的代码,如 var a = 1if...elsefor

模板中只能使用表达式,因为模板需要计算出一个值来显示。

访问限制

模板表达式只能访问以下内容:

  • 全局变量:MathDateArray
  • Vue 实例的属性和方法
  • 用户自定义的全局变量(需通过 Vue.prototype 添加)
// 添加全局变量
Vue.prototype.$appName = 'My App'

// 模板中使用
{{ $appName }}

原始 HTML

双大括号会将数据解释为普通文本,而非 HTML 代码。如果需要输出真正的 HTML,使用 v-html 指令:

<div id="app">
  <!-- 普通文本 -->
  <p>使用双大括号: {{ rawHtml }}</p>
  
  <!-- 原始 HTML -->
  <p>使用 v-html: <span v-html="rawHtml"></span></p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    rawHtml: '<strong style="color: red;">这是红色的文字</strong>'
  }
})
</script>

渲染结果:

使用双大括号: <strong style="color: red;">这是红色的文字</strong>
使用 v-html: 这是红色的文字(红色加粗)

安全警告

在网站上动态渲染任意 HTML 是非常危险的,容易导致 XSS 攻击。只对可信内容使用 HTML 插值,永远不要用在用户提交的内容上

// ❌ 危险:用户输入可能包含恶意脚本
data: {
  userContent: '<script>alert("XSS")</script>'
}

// ✅ 安全:只渲染可信内容
data: {
  trustedContent: '<strong>安全的 HTML</strong>'
}

属性绑定

双大括号不能用在 HTML 属性上,需要使用 v-bind 指令:

<!-- ❌ 错误:双大括号不能用在属性中 -->
<div id="{{ dynamicId }}"></div>

<!-- ✅ 正确:使用 v-bind -->
<div v-bind:id="dynamicId"></div>

<!-- 简写 -->
<div :id="dynamicId"></div>

使用过滤器

Vue 2 支持在插值表达式中使用过滤器:

<div id="app">
  <p>{{ message | capitalize }}</p>
  <p>{{ price | currency('¥') }}</p>
  <p>{{ date | formatDate | uppercase }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'hello vue',
    price: 99.9,
    date: '2024-01-15'
  },
  filters: {
    capitalize: function(value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    },
    currency: function(value, symbol) {
      return symbol + value.toFixed(2)
    },
    formatDate: function(value) {
      return value.replace(/-/g, '/')
    },
    uppercase: function(value) {
      return value.toUpperCase()
    }
  }
})
</script>

渲染结果:

Hello vue
¥99.90
2024/01/15

注意:Vue 3 已移除过滤器功能,推荐使用计算属性或方法代替。

缩写

Vue 为常用指令提供了缩写:

完整写法缩写
v-bind:href="url":href="url"
v-on:click="handler"@click="handler"
v-slot:header#header

缩写让模板更简洁,在实际开发中广泛使用。

小结

语法用途示例
{{ }}文本插值{{ message }}
v-html原始 HTML<span v-html="raw"></span>
v-bind属性绑定<div :id="id"></div>
``过滤器

插值表达式是 Vue 模板的基础,掌握它是学习 Vue 的第一步。