表达式 #

一、表达式基础 #

1.1 什么是表达式? #

表达式是可以被求值并返回结果的代码片段。在 Astro 模板中,使用 {} 包裹表达式:

astro
---
const name = "张三";
const age = 25;
---

<!-- 简单表达式 -->
<p>{name}</p>
<p>{age}</p>

<!-- 计算表达式 -->
<p>{age + 5}</p>
<p>{age * 2}</p>

1.2 表达式类型 #

类型 示例 说明
变量 {name} 直接引用变量
字面量 {42}, {'text'} 直接使用值
算术运算 {a + b} 数学计算
比较运算 {a > b} 返回布尔值
逻辑运算 {a && b} 逻辑运算
函数调用 {fn()} 调用函数
三元运算 {a ? b : c} 条件选择
模板字符串 {`text ${var}`} 字符串插值

二、变量表达式 #

2.1 基本变量 #

astro
---
const title = "欢迎";
const count = 100;
const isActive = true;
---

<h1>{title}</h1>
<p>数量: {count}</p>
<p>状态: {isActive ? '激活' : '未激活'}</p>

2.2 对象属性 #

astro
---
const user = {
  name: "张三",
  age: 25,
  address: {
    city: "北京",
    country: "中国"
  }
};
---

<p>姓名: {user.name}</p>
<p>年龄: {user.age}</p>
<p>城市: {user.address.city}</p>

2.3 数组元素 #

astro
---
const colors = ['红色', '绿色', '蓝色'];
const numbers = [1, 2, 3, 4, 5];
---

<p>第一个颜色: {colors[0]}</p>
<p>第三个颜色: {colors[2]}</p>
<p>数组长度: {numbers.length}</p>

2.4 可选链 #

astro
---
const user = {
  name: "张三",
  profile: null
};
---

<p>姓名: {user.name}</p>
<p>简介: {user.profile?.bio ?? '暂无简介'}</p>

三、运算符表达式 #

3.1 算术运算符 #

astro
---
const a = 10;
const b = 3;
---

<p>加法: {a + b}</p>       <!-- 13 -->
<p>减法: {a - b}</p>       <!-- 7 -->
<p>乘法: {a * b}</p>       <!-- 30 -->
<p>除法: {a / b}</p>       <!-- 3.333... -->
<p>取余: {a % b}</p>       <!-- 1 -->
<p>幂运算: {a ** 2}</p>    <!-- 100 -->

3.2 比较运算符 #

astro
---
const a = 10;
const b = 20;
const str1 = "hello";
const str2 = "world";
---

<p>{a > b}</p>           <!-- false -->
<p>{a < b}</p>           <!-- true -->
<p>{a >= 10}</p>         <!-- true -->
<p>{a === 10}</p>        <!-- true -->
<p>{a !== 10}</p>        <!-- false -->
<p>{str1 === str2}</p>   <!-- false -->

3.3 逻辑运算符 #

astro
---
const isLoggedIn = true;
const isAdmin = false;
const hasPermission = true;
---

<p>{isLoggedIn && isAdmin}</p>              <!-- false -->
<p>{isLoggedIn && hasPermission}</p>        <!-- true -->
<p>{isLoggedIn || isAdmin}</p>              <!-- true -->
<p>{!isLoggedIn}</p>                        <!-- false -->
<p>{isLoggedIn && '欢迎回来'}</p>           <!-- 欢迎回来 -->
<p>{isAdmin && '管理员权限'}</p>            <!-- false -->

3.4 空值合并运算符 #

astro
---
const name = null;
const age = undefined;
const city = "北京";
---

<p>{name ?? '匿名'}</p>     <!-- 匿名 -->
<p>{age ?? 0}</p>          <!-- 0 -->
<p>{city ?? '未知'}</p>    <!-- 北京 -->

四、函数表达式 #

4.1 调用函数 #

astro
---
function greet(name) {
  return `你好,${name}!`;
}

function formatDate(date) {
  return new Date(date).toLocaleDateString('zh-CN');
}

function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price, 0);
}

const name = "张三";
const items = [
  { name: '商品A', price: 100 },
  { name: '商品B', price: 200 }
];
---

<p>{greet(name)}</p>
<p>日期: {formatDate(new Date())}</p>
<p>总价: {calculateTotal(items)}</p>

4.2 内置方法 #

astro
---
const text = "Hello World";
const numbers = [1, 2, 3, 4, 5];
---

<p>大写: {text.toUpperCase()}</p>
<p>小写: {text.toLowerCase()}</p>
<p>长度: {text.length}</p>
<p>数组求和: {numbers.reduce((a, b) => a + b, 0)}</p>
<p>数组最大值: {Math.max(...numbers)}</p>

4.3 箭头函数 #

astro
---
const double = x => x * 2;
const add = (a, b) => a + b;
const format = (str) => str.trim().toLowerCase();
---

<p>双倍: {double(5)}</p>
<p>相加: {add(3, 4)}</p>
<p>格式化: {format('  HELLO  ')}</p>

4.4 IIFE(立即执行函数) #

astro
---
const price = 100;
---

<p>折扣价: {(() => {
  const discount = 0.8;
  return price * discount;
})()}</p>

五、三元表达式 #

5.1 基本用法 #

astro
---
const isLoggedIn = true;
const role = 'admin';
const count = 5;
---

<p>{isLoggedIn ? '已登录' : '未登录'}</p>
<p>{role === 'admin' ? '管理员' : '普通用户'}</p>
<p>{count > 0 ? `有 ${count} 条消息` : '无消息'}</p>

5.2 嵌套三元 #

astro
---
const score = 85;
---

<p>
  成绩等级: {
    score >= 90 ? '优秀' :
    score >= 80 ? '良好' :
    score >= 60 ? '及格' : '不及格'
  }
</p>

5.3 在属性中使用 #

astro
---
const isActive = true;
const isDisabled = false;
---

<button 
  class={isActive ? 'btn-active' : 'btn-inactive'}
  disabled={isDisabled}
>
  {isDisabled ? '不可用' : '点击'}
</button>

六、模板字符串 #

6.1 基本用法 #

astro
---
const name = "张三";
const age = 25;
const city = "北京";
---

<p>{`姓名: ${name}`}</p>
<p>{`年龄: ${age} 岁`}</p>
<p>{`地址: ${city}`}</p>

6.2 多行字符串 #

astro
---
const title = "标题";
const content = "内容";
---

<pre>{`
标题: ${title}
内容: ${content}
`}</pre>

6.3 表达式嵌入 #

astro
---
const a = 10;
const b = 20;
const items = ['苹果', '香蕉'];
---

<p>{`计算: ${a} + ${b} = ${a + b}`}</p>
<p>{`水果: ${items.join(', ')}`}</p>
<p>{`时间: ${new Date().toLocaleString()}`}</p>

七、数组表达式 #

7.1 数组方法 #

astro
---
const numbers = [1, 2, 3, 4, 5];
const words = ['apple', 'banana', 'cherry'];
---

<p>过滤: {numbers.filter(n => n > 2).join(', ')}</p>
<p>映射: {numbers.map(n => n * 2).join(', ')}</p>
<p>查找: {numbers.find(n => n > 3)}</p>
<p>包含: {numbers.includes(3) ? '包含' : '不包含'}</p>
<p>连接: {words.join(' - ')}</p>

7.2 数组解构 #

astro
---
const [first, second, ...rest] = [1, 2, 3, 4, 5];
---

<p>第一个: {first}</p>
<p>第二个: {second}</p>
<p>剩余: {rest.join(', ')}</p>

八、对象表达式 #

8.1 对象属性访问 #

astro
---
const user = {
  name: "张三",
  age: 25,
  skills: ['JavaScript', 'TypeScript']
};

const key = 'name';
---

<p>点语法: {user.name}</p>
<p>括号语法: {user['age']}</p>
<p>动态键: {user[key]}</p>
<p>嵌套: {user.skills.join(', ')}</p>

8.2 对象解构 #

astro
---
const { name, age, city = '未知' } = {
  name: "张三",
  age: 25
};
---

<p>姓名: {name}</p>
<p>年龄: {age}</p>
<p>城市: {city}</p>

九、类型转换 #

9.1 字符串转换 #

astro
---
const num = 42;
const bool = true;
const arr = [1, 2, 3];
---

<p>{String(num)}</p>
<p>{num.toString()}</p>
<p>{String(bool)}</p>
<p>{JSON.stringify(arr)}</p>

9.2 数字转换 #

astro
---
const str = "42";
const float = "3.14";
---

<p>{Number(str)}</p>
<p>{parseInt(str)}</p>
<p>{parseFloat(float)}</p>
<p>{+str}</p>

十、复杂表达式示例 #

10.1 格式化价格 #

astro
---
function formatPrice(price, currency = 'CNY') {
  return new Intl.NumberFormat('zh-CN', {
    style: 'currency',
    currency
  }).format(price);
}

const price = 1234.56;
---

<p>价格: {formatPrice(price)}</p>
<p>美元: {formatPrice(price, 'USD')}</p>

10.2 时间格式化 #

astro
---
function formatTime(date, format = 'full') {
  const d = new Date(date);
  const formats = {
    full: { year: 'numeric', month: 'long', day: 'numeric' },
    short: { month: 'short', day: 'numeric' },
    time: { hour: '2-digit', minute: '2-digit' }
  };
  return d.toLocaleDateString('zh-CN', formats[format]);
}

const now = new Date();
---

<p>完整: {formatTime(now, 'full')}</p>
<p>简短: {formatTime(now, 'short')}</p>
<p>时间: {formatTime(now, 'time')}</p>

10.3 数据统计 #

astro
---
const orders = [
  { id: 1, amount: 100, status: 'completed' },
  { id: 2, amount: 200, status: 'pending' },
  { id: 3, amount: 150, status: 'completed' },
  { id: 4, amount: 300, status: 'completed' },
];

const totalAmount = orders.reduce((sum, o) => sum + o.amount, 0);
const completedOrders = orders.filter(o => o.status === 'completed');
const avgAmount = totalAmount / orders.length;
---

<p>总金额: {totalAmount}</p>
<p>已完成: {completedOrders.length} 单</p>
<p>平均金额: {avgAmount.toFixed(2)}</p>

十一、表达式最佳实践 #

11.1 保持简洁 #

astro
---
// ✅ 好的做法:将复杂逻辑提取到函数
function getStatusText(status) {
  const statusMap = {
    pending: '待处理',
    processing: '处理中',
    completed: '已完成',
    cancelled: '已取消'
  };
  return statusMap[status] || '未知';
}

const status = 'completed';
---

<p>状态: {getStatusText(status)}</p>

---
// ❌ 不好的做法:模板中复杂表达式
const status = 'completed';
---

<p>状态: {
  status === 'pending' ? '待处理' :
  status === 'processing' ? '处理中' :
  status === 'completed' ? '已完成' :
  status === 'cancelled' ? '已取消' : '未知'
}</p>

11.2 使用类型保护 #

astro
---
function getLength(value: string | string[]): number {
  if (typeof value === 'string') {
    return value.length;
  }
  return value.length;
}

const text = "Hello";
const list = ['a', 'b', 'c'];
---

<p>文本长度: {getLength(text)}</p>
<p>列表长度: {getLength(list)}</p>

十二、总结 #

表达式核心要点:

text
┌─────────────────────────────────────────────────────┐
│                 表达式核心要点                       │
├─────────────────────────────────────────────────────┤
│                                                     │
│  📝 变量表达式    直接引用变量值                     │
│                                                     │
│  🔢 运算符        算术、比较、逻辑运算               │
│                                                     │
│  📞 函数调用      调用函数获取返回值                 │
│                                                     │
│  ❓ 三元表达式    条件选择值                         │
│                                                     │
│  📋 模板字符串    字符串插值和格式化                 │
│                                                     │
│  📦 解构          数组和对象解构                     │
│                                                     │
└─────────────────────────────────────────────────────┘

下一步,让我们学习 条件渲染,掌握条件显示内容的方法!

最后更新:2026-03-28