本文目录导读:

在Laravel中设计邮件通知视图时,需要兼顾美观、功能性和跨客户端兼容性,以下是系统化的设计指南和最佳实践:
项目结构规划
resources/views/emails/
├── layouts/
│ ├── default.blade.php # 主布局
│ └── notification.blade.php # 通知特定布局
├── notifications/
│ ├── order-confirmation.blade.php
│ ├── password-reset.blade.php
│ └── welcome.blade.php
├── partials/
│ ├── header.blade.php
│ ├── footer.blade.php
│ └── button.blade.php
└── components/
└── alert.blade.php
基础布局设计
主布局 (layouts/default.blade.php)
@php
$appName = config('app.name');
$primaryColor = '#3490dc';
@endphp
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">{{ $title ?? $appName }}</title>
<style>
/* 响应式设计 */
@media only screen and (max-width: 600px) {
.container { width: 100% !important; padding: 0 20px !important; }
.header { padding: 20px 15px !important; }
.content { padding: 30px 20px !important; }
.button { display: block !important; width: 100% !important; }
}
/* 主题变量 */
:root {
--primary-color: {{ $primaryColor }};
--text-primary: #333333;
--text-secondary: #666666;
--background: #f8f9fa;
--border: #e9ecef;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
background-color: var(--background);
color: var(--text-primary);
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
}
/* 容器 */
.container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* 头部 */
.header {
background-color: var(--primary-color);
padding: 30px 40px;
text-align: center;
}
.header img {
max-width: 150px;
max-height: 60px;
object-fit: contain;
}
.header h1 {
color: #ffffff;
font-size: 24px;
margin: 0;
font-weight: 600;
}
/* 内容区域 */
.content {
padding: 40px;
line-height: 1.6;
}
h2 {
color: var(--text-primary);
font-size: 20px;
margin-bottom: 20px;
}
p {
margin: 0 0 15px;
color: var(--text-secondary);
font-size: 16px;
}
/* 按钮样式 */
.button {
display: inline-block;
background-color: var(--primary-color);
color: #ffffff !important;
text-decoration: none;
padding: 12px 30px;
border-radius: 4px;
font-weight: 500;
margin: 20px 0;
text-align: center;
font-size: 16px;
transition: opacity 0.3s;
}
.button:hover {
opacity: 0.9;
}
/* 事件块 */
.event-details {
background-color: var(--background);
border-left: 4px solid var(--primary-color);
padding: 20px;
margin: 20px 0;
border-radius: 4px;
}
.event-details h3 {
margin: 0 0 10px;
font-size: 18px;
color: var(--text-primary);
}
.event-details p {
margin: 5px 0;
font-size: 14px;
}
/* 表格样式 */
.table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.table th, .table td {
padding: 12px;
border: 1px solid var(--border);
text-align: left;
}
.table th {
background-color: var(--background);
font-weight: 600;
}
/* 警告框 */
.alert {
padding: 15px 20px;
border-radius: 4px;
margin: 20px 0;
font-size: 14px;
}
.alert-danger {
background-color: #f8d7da;
border: 1px solid #f5c6cb;
color: #721c24;
}
.alert-success {
background-color: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
}
/* 页脚 */
.footer {
padding: 20px 40px;
text-align: center;
background-color: #f8f9fa;
border-top: 1px solid var(--border);
font-size: 13px;
color: #999;
}
.footer a {
color: #666;
text-decoration: none;
}
.footer a:hover {
color: var(--primary-color);
}
</style>
</head>
<body>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="center" style="padding: 40px 20px;">
<table class="container" cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="header">
@include('emails.partials.header')
</td>
</tr>
<tr>
<td class="content">
{{ $slot }}
</td>
</tr>
<tr>
<td class="footer">
@include('emails.partials.footer')
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
通知视图示例
订单确认通知 (order-confirmation.blade.php)
@component('emails.layouts.notification', [ => '订单确认',
'user' => $user
])
<h2>感谢您的购买,{{ $user->name }}!</h2>
<p>您的订单已成功确认,以下是您的订单详情:</p>
<div class="event-details">
<h3>订单 #{{ $order->id }}</h3>
<p><strong>订单日期:</strong>{{ $order->created_at->format('Y-m-d H:i') }}</p>
<p><strong>支付方式:</strong>{{ $order->payment_method }}</p>
<p><strong>预计送达:</strong>{{ $order->expected_delivery_date }}</p>
</div>
<h3 style="margin-top: 30px;">商品清单</h3>
<table class="table">
<thead>
<tr>
<th>商品</th>
<th>数量</th>
<th>价格</th>
<th>小计</th>
</tr>
</thead>
<tbody>
@foreach($order->items as $item)
<tr>
<td>{{ $item->product_name }}</td>
<td>{{ $item->quantity }}</td>
<td>{{ number_format($item->price, 2, ',', '.') }} 元</td>
<td>{{ number_format($item->quantity * $item->price, 2, ',', '.') }} 元</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<td colspan="3" style="text-align: right;"><strong>总计:</strong></td>
<td><strong>{{ number_format($order->total, 2, ',', '.') }} 元</strong></td>
</tr>
</tfoot>
</table>
<div style="text-align: center; margin-top: 30px;">
<a href="{{ url('/order/'.$order->id) }}" class="button">查看订单详情</a>
</div>
<p style="margin-top: 30px; font-size: 14px; color: #999;">
如对订单有任何疑问,请在 30 天内联系客服 <a href="mailto:{{ config('mail.support_email') }}">{{ config('mail.support_email') }}</a>
</p>
@endcomponent
响应式按钮组件
{{-- resources/views/emails/components/button.blade.php --}}
@props([
'url' => '#',
'color' => '#3490dc',
'width' => 'auto'
])
<table role="presentation" cellpadding="0" cellspacing="0" style="margin: 20px 0;">
<tr>
<td style="border-radius: 4px; background-color: {{ $color }}; padding: 12px 30px;">
<a href="{{ $url }}" style="color: #ffffff; text-decoration: none; display: inline-block; font-size: 16px;">
{{ $slot }}
</a>
</td>
</tr>
</table>
使用Laravel Mail类
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Notifications\Notification;
class OrderConfirmationMail extends Mailable
{
use Queueable, SerializesModels;
public $order;
public $user;
public function __construct($order, $user)
{
$this->order = $order;
$this->user = $user;
}
public function build()
{
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject('订单确认')
->view('emails.notifications.order-confirmation')
->with([
'order' => $this->order,
'user' => $this->user,
'title' => '订单已确认'
]);
}
}
使用通知系统
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class OrderShipped extends Notification implements ShouldQueue
{
use Queueable;
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('您的订单已发货')
->greeting('您好,' . $notifiable->name . '!')
->line('您的订单已发货,正在运输途中。')
->line('订单号:' . $this->order->tracking_number)
->action('追踪订单', url('/track-order/' . $this->order->tracking_number))
->line('感谢您选择我们的服务!')
->view('emails.notifications.custom-view', [
'order' => $this->order,
'user' => $notifiable
]);
}
}
最佳实践
响应式设计检查清单
- 使用
table布局确保Outlook兼容 - 设置
max-width保证移动端显示 - 确保按钮在移动端全宽显示
- 使用
@media查询处理小屏适配
性能优化
- 避免使用过大的图片
- 使用CSS内联样式(可借助CSS inliner工具)
- 将邮件通知加入队列处理
测试建议
Mail::fake();
Mail::assertSent(OrderConfirmationMail::class, function ($mail) {
return $mail->hasTo('test@example.com');
});
个性化模板变量
@foreach($items as $item)
<tr>
<td>{{ $item->name }}</td>
<td>{{ $item->price }}</td>
</tr>
@endforeach
@if($hasDiscount)
<div class="alert alert-success">
您获得了 {{ $discount }} 元折扣!
</div>
@endif
@isset($referral)
<p>您的邀请码:{{ $referral->code }}</p>
@endisset
这种设计确保了邮件在各种设备和客户端上的良好表现,同时保持代码的可维护性和可复用性,根据项目需求,可以进一步定制样式和组件。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播