Blade模板循环中@include子模板@section变量取值异常求助
这个问题我之前也踩过坑!核心原因是Blade的@section指令在模板继承机制中的变量作用域特性:当你在循环里引入子视图时,子视图中@section块内的变量并没有被正确绑定到当前循环的迭代实例,反而会因为模板编译的上下文特性,一直引用第一次循环的变量值。
问题分析
你直接输出{{$campaign}}正常,是因为这部分属于子视图的直接渲染内容,变量作用域完全属于当前循环上下文;但@section('options')里的内容,Blade会把它先收集起来,最终在父模板(admin.includes.base_campaign_card)的@yield('options')位置统一渲染,这部分内容的变量作用域并没有和当前循环的迭代绑定,导致所有循环都复用了第一次的变量值。
解决方案
有两种简单有效的解决方式,你可以根据现有模板结构选择:
1. 用局部变量捕获当前循环的$campaign
在子视图admin.includes.campaign_card中,先把$campaign赋值给一个局部变量,再在@section里使用这个局部变量,强制绑定当前循环的实例:
{{-- admin.includes.campaign_card --}} @extends('admin.includes.base_campaign_card') {{-- 先捕获当前循环的变量到局部变量 --}} @php $currentCampaign = $campaign; @endphp {{-- 直接输出正常的原有内容 --}} {{ $campaign->title }} @section('options') {{-- 使用局部变量而非原变量 --}} <div class="option-buttons"> <a href="/campaigns/{{ $currentCampaign->id }}/edit">编辑</a> <button data-id="{{ $currentCampaign->id }}" class="delete-btn">删除</button> </div> @endsection
2. 绕过@section,改用参数传递动态内容
如果你的options区块内容逻辑不复杂,可以把这部分内容作为参数传递给子视图,彻底避开@section的作用域问题:
首先修改循环中的@include调用,传递options片段:
@foreach($campaignList as $campaign) <div class="col-md-{{12/$columns}}"> @include('admin.includes.campaign_card',[ 'campaign'=>$campaign, 'link'=>true, 'options' => view('admin.includes.campaign_options', ['campaign' => $campaign]) ]) </div> @endforeach
然后修改子视图admin.includes.campaign_card,直接输出传递过来的$options:
{{-- admin.includes.campaign_card --}} @extends('admin.includes.base_campaign_card') {{-- 直接输出options内容 --}} {!! $options !!} {{-- 其他原有内容 --}} {{ $campaign->title }}
最后创建admin.includes.campaign_options视图存放原@section('options')的内容:
{{-- admin.includes.campaign_options --}} <div class="option-buttons"> <a href="/campaigns/{{ $campaign->id }}/edit">编辑</a> <button data-id="{{ $campaign->id }}" class="delete-btn">删除</button> </div>
验证效果
两种方法都能解决你遇到的变量取值异常问题,第一种适合原有模板结构改动小的场景,第二种逻辑更清晰,适合复杂的动态内容场景。
内容的提问来源于stack exchange,提问作者ka_lin

