好的,我们来详细讲解 Vue 中最基础的数据展示方式:文本插值 和在其内部使用的 JavaScript 表达式。
1. 文本插值 (Text Interpolation)
知识点 :
文本插值是 Vue 中最基本的数据绑定形式。它使用"Mustache"语法(双大括号 {``{ }}
)将数据直接渲染到 HTML 的文本内容中。
- 核心作用 : 将 Vue 实例中
setup
函数返回的数据,动态地显示在页面的指定位置。 - 响应式: 当大括号内所依赖的数据发生变化时,插值所在的部分会自动更新,以反映最新的数据。这正是 Vue 响应式系统的核心体现。
- 纯文本 : 插值会将其内容作为纯文本来处理,而不是 HTML。如果你想渲染 HTML,需要使用我们之前讨论过的
v-html
指令。
2. JavaScript 表达式 (JavaScript Expressions)
知识点 :
双大括号 {``{ }}
内部不仅仅能放一个简单的变量名,它还支持单个 JavaScript 表达式。这意味着你可以在里面进行计算、调用方法或执行简单的逻辑判断。
Vue 对这里的表达式有明确的限制:
- 必须是表达式 (Expression) : 一个表达式是任何可以产生一个值的代码片段。例如
user.name
、count + 1
、isOk ? '是' : '否'
。 - 不能是语句 (Statement) : 语句是执行操作但不一定返回值。例如
let a = 1
、if (x > 1) { ... }
、for (...)
都是语句,它们在插值中是无效的。 - 访问限制 : 表达式只能访问在
setup
中返回的属性、全局白名单内的对象(如Math
、Date
)和一些 Vue 内置的辅助函数。你不能访问自己定义的全局变量。
示例代码
下面是一个完整的 HTML 文件,演示了文本插值和各种合法的 JavaScript 表达式。
你可以将此代码保存为 .html
文件,并在浏览器中打开查看效果。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 3 文本插值与表达式 (CDN)</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; padding: 20px; font-size: 1.1rem; }
#app { max-width: 700px; margin: 0 auto; padding: 25px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.demo-section { padding: 15px; border: 1px solid #e0e0e0; border-radius: 5px; margin-bottom: 20px; }
.demo-section h3 { margin-top: 0; color: #42b883; }
code { background-color: #f0f0f0; padding: 2px 5px; border-radius: 3px; }
.note { color: #d9534f; font-size: 0.9em; margin-top: 10px; }
</style>
</head>
<body>
<div id="app">
<h1>文本插值 ({{ }}) 与表达式</h1>
<div class="demo-section">
<h3>1. 基本用法</h3>
<p>欢迎, {{ username }}!</p>
</div>
<div class="demo-section">
<h3>2. 算术运算</h3>
<p>商品单价: {{ price }} 元</p>
<p>商品数量: {{ quantity }}</p>
<p>总价: <strong>{{ price * quantity }}</strong> 元</p>
</div>
<div class="demo-section">
<h3>3. 访问对象属性</h3>
<p>用户信息: {{ user.name }} ({{ user.email }})</p>
</div>
<div class="demo-section">
<h3>4. 使用方法调用</h3>
<p>姓名倒序: <strong>{{ reverseName(user.name) }}</strong></p>
</div>
<div class="demo-section">
<h3>5. 使用三元运算符</h3>
<p>
账户状态:
<span :style="{ color: isActive ? 'green' : 'red' }">
{{ isActive ? '已激活' : '未激活' }}
</span>
</p>
</div>
<div class="demo-section">
<h3>6. 复杂的表达式 (但保持简洁)</h3>
<p>
格式化消息:
<code>{{ message.toUpperCase().split('').reverse().join('') }}</code>
</p>
</div>
<div class="demo-section">
<h3>7. 无效的用法 (语句)</h3>
<p>下面的代码在 Vue 模板中会报错,这里仅作说明:</p>
<ul>
<li><code>{{ let a = 1 }}</code> (这是声明语句)</li>
<li><code>{{ if (isActive) { return 'Active' } }}</code> (这是流控制语句)</li>
</ul>
<p class="note">注意:你不能在 `{{ }}` 中使用 `if/else`,但可以使用三元运算符 `( ? : )` 来实现类似的效果。</p>
</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const { createApp, ref, reactive } = Vue;
const app = createApp({
setup() {
// 1. 基本数据
const username = ref('张三');
// 2. 用于算术运算的数据
const price = ref(15);
const quantity = ref(3);
// 3. 对象数据
const user = reactive({
name: '李四',
email: 'lisi@example.com'
});
// 4. 定义一个方法
const reverseName = (name) => {
return name.split('').reverse().join('');
};
// 5. 用于三元运算符的数据
const isActive = ref(true);
// 6. 用于复杂表达式的数据
const message = ref('Hello Vue');
// 将所有需要被模板访问的数据和方法返回
return {
username,
price,
quantity,
user,
reverseName,
isActive,
message
};
}
});
app.mount('#app');
</script>
</body>
</html>
总结
分类 | 示例 | 描述 |
---|---|---|
基础变量 | {``{ myData }} |
直接显示 setup 中返回的 myData 的值。 |
算术运算 | {``{ count + 1 }} |
可以执行加减乘除等数学计算。 |
对象属性访问 | {``{ user.name }} |
可以访问对象的深层属性。 |
方法调用 | {``{ formatPrice(price) }} |
可以调用 setup 中返回的方法,并传入参数。 |
三元表达式 | {``{ isVisible ? '显示' : '隐藏' }} |
是 if-else 在模板中最常见的替代方案。 |
其他表达式 | {``{ message.split('').reverse().join('') }} |
任何能返回一个值的 JS 表达式链都是有效的。 |
最佳实践 :虽然模板中支持复杂的表达式,但为了保持模板的声明性 和可读性 ,推荐将过于复杂的逻辑封装在方法 或计算属性 (computed
property)中。这样可以让模板代码更清晰、更易于维护。