从Laravel 7.25开始,Blade现在包含一个新的@once组件,该组件只能渲染一次标签内的项目。https://laravel.com/docs/8.x/blade#the-once-directive
在下面的答案中,我假设您熟悉Blade扩展。这种方法已经在Laravel 5.2和5.3上进行了测试(请参阅下面的注释)。
在测试了Ismail RBOUH的答案(所以请阅读它)之后,似乎解决方案有两个问题:
1-$isDisplayed变量与其他包含的小部件不在同一范围内,因此每个@include将其脚本推送到堆栈。因此,我将其更改为:
Blade::directive('pushonce', function ($expression) {
$isDisplayed = '__pushonce_'.trim(substr($expression, 2, -2));
return "<?php if(!isset(\$__env->{$isDisplayed})): \$__env->{$isDisplayed} = true; \$__env->startPush{$expression}; ?>";
});
Blade::directive('endpushonce', function ($expression) {
return '<?php $__env->stopPush(); endif; ?>';
});
2-解决方案将@pushonce的使用限制为一个小部件。即,在2个或多个小部件(widget1.blade.php,widget2.blade.php,...)的情况下,它可以阻止推送其他小部件脚本。因此,我使用以下代码将域添加到@pushonce:
Blade::directive('pushonce', function ($expression) {
$domain = explode(':', trim(substr($expression, 2, -2)));
$push_name = $domain[0];
$push_sub = $domain[1];
$isDisplayed = '__pushonce_'.$push_name.'_'.$push_sub;
return "<?php if(!isset(\$__env->{$isDisplayed})): \$__env->{$isDisplayed} = true; \$__env->startPush('{$push_name}'); ?>";
});
Blade::directive('endpushonce', function ($expression) {
return '<?php $__env->stopPush(); endif; ?>';
});
用法:
小部件1.刀片.php
@pushonce('scripts:widget1')
<script src="{{ asset('js/foo.js') }}"></script>
<script>
...
</script>
@endpushonce
小部件2.刀片.php
@pushonce('scripts:widget2')
<script src="{{ asset('js/bar.js') }}"></script>
<script>
...
</script>
@endpushonce
注意 L 5.3:更改以下行:
$domain = explode(':', trim(substr($expression, 2, -2)));
自
$domain = explode(':', trim(substr($expression, 1, -1)));