@push 是 Laravel Blade 模板引擎中的一个指令,用于将内容推送到命名堆栈中,与 @stack 指令配合使用。
基本概念
@stack
- 定义一个可以接收内容的"堆栈"区域
- 通常放在布局模板中
@push
- 向指定的堆栈推送内容
- 可以多次调用,内容会按推送顺序排列
基本语法
{{-- 在布局文件中定义堆栈 --}}
@stack('stack-name')
{{-- 在子视图中推送内容 --}}
@push('stack-name')
<!-- 推送的内容 -->
@endpush
使用示例
1. 基础使用
布局文件:layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
<title>App</title>
@stack('styles')
</head>
<body>
@yield('content')
@stack('scripts')
</body>
</html>
子视图文件:home.blade.php
@extends('layouts.app')
@section('content')
<h1>Home Page</h1>
@endsection
@push('styles')
<link rel="stylesheet" href="/css/home.css">
@endpush
@push('scripts')
<script src="/js/home.js"></script>
@endpush
2. 多页面使用场景
多个页面向同一个堆栈推送内容
page1.blade.php:
@extends('layouts.app')
@push('scripts')
<script src="/js/page1.js"></script>
@endpush
page2.blade.php:
@extends('layouts.app')
@push('scripts')
<script src="/js/page2.js"></script>
<script>
console.log('Page 2 loaded');
</script>
@endpush
最终 @stack('scripts') 会按推送顺序渲染所有内容。
高级用法
1. 推送变量内容
@php
$scriptPath = config('app.env') === 'production'
? '/js/app.min.js'
: '/js/app.js';
@endphp
@push('scripts')
<script src="{{ $scriptPath }}"></script>
@endpush
2. 条件推送
@if($needsChart)
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
@endpush
@endif
3. 内联推送(Blade 8.x+)
@push('scripts', '<script>console.log("inline")</script>')
4. 推送前预置内容
{{-- 在布局中先定义一些默认内容 --}}
@stack('styles')
<link rel="stylesheet" href="/css/default.css">
@endstack
{{-- 子视图中会追加到默认内容之后 --}}
@push('styles')
<link rel="stylesheet" href="/css/custom.css">
@endpush
与其他指令的对比
@push vs @section
{{-- @section 用于替换整个区块 --}}
@section('sidebar')
@parent {{-- 保留父模板内容 --}}
<p>Additional content</p>
@endsection
{{-- @push 总是追加内容 --}}
@push('scripts')
<script>/* 总是添加 */</script>
@endpush
@push vs @include
{{-- @include 包含完整文件 --}}
@include('partials.scripts')
{{-- @push 推送特定内容块 --}}
@push('scripts')
<!-- 特定代码 -->
@endpush
实际应用场景
1. 页面特定CSS/JS
{{-- 只在某些页面加载特定资源 --}}
@push('styles')
<style>
.page-specific {
color: red;
}
</style>
@endpush
2. 动态组件脚本
{{-- 组件文件 --}}
<div id="component-{{ $id }}">Component Content</div>
@push('scripts')
<script>
document.getElementById('component-{{ $id }}').addEventListener('click', function() {
// 组件逻辑
});
</script>
@endpush
3. Meta标签管理
{{-- 布局文件 --}}
<head>
<meta charset="UTF-8">
@stack('meta')
</head>
{{-- 子视图 --}}
@push('meta')
<meta name="description" content="{{ $pageDescription }}">
<meta property="og:title" content="{{ $pageTitle }}">
@endpush
最佳实践
-
命名规范:使用有意义的堆栈名称
@stack('header-scripts') @stack('footer-scripts') @stack('inline-styles') -
避免重复:确保相同的脚本不会被多次推送
@unless(in_array('chartjs', $loadedScripts)) @push('scripts') <script src="/chartjs.js"></script> @endpush @php $loadedScripts[] = 'chartjs'; @endphp @endunless -
性能优化:合并推送内容
@push('scripts') <script> // 页面初始化代码 $(document).ready(function() { {{-- 多个初始化操作合并 --}} initTable(); initChart(); initForm(); }); </script> @endpush
注意事项
- 作用域:
@push内容在堆栈被渲染时才输出 - 顺序:推送顺序就是渲染顺序
- 嵌套:可以在
@include的文件中使用@push - 性能:过多的推送可能影响性能,考虑合并内容
通过 @push 和 @stack 的组合,可以创建灵活、可维护的模板结构,特别适合需要动态添加CSS、JavaScript或HTML片段的场景。