Mailable 与 Markdown 邮件模板
High Contrast
Dark Mode
Light Mode
Sepia
Forest
1 min read171 words

Mailable 与 Markdown 邮件模板

Laravel 的 Mailable 类把邮件内容和发送逻辑封装在一起——每种邮件对应一个类。Markdown 邮件模板让你用简单的 Markdown 语法写出样式完整、响应式的 HTML 邮件,不需要手写 HTML/CSS。


创建 Mailable

php artisan make:mail TaskDueReminder --markdown=emails.tasks.due-reminder
php artisan make:mail WelcomeMail --markdown=emails.auth.welcome
<?php
// app/Mail/TaskDueReminder.php
namespace App\Mail;
use App\Models\Task;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class TaskDueReminder extends Mailable
{
use Queueable, SerializesModels;
public function __construct(
public readonly Task $task,
public readonly User $user
) {}
// 邮件信封(主题、发件人、收件人)
public function envelope(): Envelope
{
return new Envelope(
subject: "提醒:任务《{$this->task->title}》即将到期",
// from: new Address('noreply@taskflow.app', 'TaskFlow'),  // 覆盖默认发件人
);
}
// 邮件内容
public function content(): Content
{
return new Content(
markdown: 'emails.tasks.due-reminder',
// 传给模板的变量
with: [
'daysLeft' => now()->diffInDays($this->task->due_date),
],
);
}
// 附件
public function attachments(): array
{
return [];
// 如果需要附件:
// return [
//     Attachment::fromStorage("tasks/{$this->task->id}/brief.pdf")
//         ->as('项目简介.pdf')
//         ->withMime('application/pdf'),
// ];
}
}

Markdown 邮件模板

{{-- resources/views/emails/tasks/due-reminder.blade.php --}}
@component('mail::message')
# 任务即将到期提醒
Hi {{ $user->name }},
你有一个任务即将到期,请及时处理:
@component('mail::panel')
**{{ $task->title }}**
优先级:{{ $task->priority }} | 截止日期:{{ $task->due_date->format('Y 年 m 月 d 日') }}
@endcomponent
@if($daysLeft <= 1)
⚠️ 距离截止日期仅剩 **不到 1 天**,请立即处理!
@else
距离截止日期还有 **{{ $daysLeft }} 天**。
@endif
@component('mail::button', ['url' => route('tasks.show', $task), 'color' => 'primary'])
查看任务详情
@endcomponent
如果你不需要此提醒,可以在任务设置中关闭通知。
感谢使用 TaskFlow,
{{ config('app.name') }}
@endcomponent

Markdown 邮件组件

{{-- 可用的内置 Markdown 组件 --}}
{{-- 按钮 --}}
@component('mail::button', ['url' => $url, 'color' => 'primary'])
点击这里   {{-- color: primary / success / error --}}
@endcomponent
{{-- 面板(高亮区块)--}}
@component('mail::panel')
这里是重要信息
@endcomponent
{{-- 表格 --}}
@component('mail::table')
| 任务名称 | 截止日期 | 状态 |
|---------|---------|------|
| 写文档 | 2024-03-25 | 待处理 |
@endcomponent
{{-- 分割线 --}}
@component('mail::subcopy')
如有问题,请联系 support@taskflow.app
@endcomponent

发送邮件

use Illuminate\Support\Facades\Mail;
use App\Mail\TaskDueReminder;
// 方式一:立即发送
Mail::to($user->email)->send(new TaskDueReminder($task, $user));
// 发给多人
Mail::to($user->email)
->cc('manager@example.com')
->bcc('audit@example.com')
->send(new TaskDueReminder($task, $user));
// 方式二:加入队列异步发送(推荐)
Mail::to($user->email)->queue(new TaskDueReminder($task, $user));
// 延迟发送
Mail::to($user->email)
->later(now()->addMinutes(30), new TaskDueReminder($task, $user));
// 方式三:Mailable 实现 ShouldQueue(自动入队)
class TaskDueReminder extends Mailable implements ShouldQueue
{
use Queueable;  // 实现 ShouldQueue 后,dispatch() 方式自动入队
}
Mail::to($user->email)->send(new TaskDueReminder($task, $user));  // 自动入队

开发环境:本地调试邮件

# .env(开发环境:把邮件写到日志,不真实发送)
MAIL_MAILER=log
# 使用 Mailpit(推荐:本地 SMTP 捕获工具)
MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
# 访问 http://localhost:8025 查看所有拦截的邮件
# Docker 启动 Mailpit
docker run -d -p 1025:1025 -p 8025:8025 axllent/mailpit
# 预览邮件渲染效果
php artisan tinker
>>> new \App\Mail\TaskDueReminder($task, $user)
# 或者在浏览器直接预览:
Route::get('/mail-preview', fn() => new App\Mail\TaskDueReminder(Task::first(), User::first()));

自定义邮件主题样式

# 发布邮件模板资源(可自定义样式)
php artisan vendor:publish --tag=laravel-mail
# 生成:resources/views/vendor/mail/
# 编辑 html/themes/default.css 自定义颜色

下一节Notification:多渠道通知系统——邮件只是通知方式之一。Laravel Notification 系统支持邮件、Slack、SMS、数据库内通知等多渠道,用一个统一的接口管理所有通知。