通常我们这样做来实现视图变量全局共享
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
class AppServiceProvider extends ServiceProvider
{
/**
* 注册任何应用服务
*
* @return void
*/
public function register()
{
//
}
/**
* 引导任何应用程序服务
*
* @return void
*/
public function boot()
{
View::share('key', 'value');
}
}
这种做法的缺点就是:不管你是否在渲染视图,这块逻辑都会执行。比如说你写一个接口,他也会执行这一块逻辑。
所以,使用视图合成器可以避免这个问题,
创建视图合成器 1
App\Http\View\Composers\GlobalStrongShopComposer
<?php
namespace App\Http\View\Composers;
use Illuminate\View\View;
use App\Repositories\AppRepository;
/**
* 配置视图全局变量
*/
class GlobalStrongShopComposer
{
public $user;
public $user_id;
public $cart;
public function __construct()
{
}
/**
* 将数据绑定到视图
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view->with('_current_currency', AppRepository::getCurrentCurrency()); //当前货币code
$view->with('_current_currency_name', AppRepository::getCurrentCurrencyName()); //当前货币名称
}
}
创建视图合成器 2
<?php
namespace App\Http\View\Composers;
use Illuminate\View\View;
use App\Repositories\CartRepository;
use App\Repositories\ShippingRepository;
use App\Repositories\RegionRepository;
class ShoppingCartComposer
{
public $user;
public $user_id;
public $cart;
public function __construct()
{
$this->user = app('strongshop')->user ?: null;
$this->user_id = $this->user ? $this->user->id : null;
$this->cart = CartRepository::getCart();
}
/**
* 将数据绑定到视图
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$user_id = $this->user_id;
$cart = $this->cart;
if (config('strongshop.showShipingFeeInCart'))
{
if ($this->user && $this->user->country_code)
{
$_user_country_code = app('strongshop')->user->country_code; //会员所属国家code
} else
{
$_user_country_code = config('strongshop.defaultCountry'); //默认国家code
}
//显示配送费用
$shipping_fee_list = ShippingRepository::getShippingFeeList($cart['cart_weight'], $_user_country_code);
$shipping_total = $shipping_fee_list[0]['fee'] ?? 0;
$view->with('_countries', RegionRepository::countries()); //国家列表
$view->with('_user_country_code', $_user_country_code); //会员所属国家code
$view->with('_shipping_options', $shipping_fee_list); //配送方式列表
} else
{
$shipping_total = false; // false 表示不显示配送费用
}
$cart['total']['shipping_total'] = $shipping_total;
//购物车
$view->with('_cart', $cart);
}
}
添加到 AppServiceProvider
每次呈现视图时都会将数据绑定到视图
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
class AppServiceProvider extends ServiceProvider
{
/**
* 注册任何应用服务
*
* @return void
*/
public function register()
{
//
}
/**
* 引导任何应用程序服务
*
* @return void
*/
public function boot()
{
// 配置视图全局变量(所有的视图都会共享)
View::composer('*', 'App\Http\View\Composers\GlobalStrongShopComposer');
//layouts 布局变量(只共享 layouts/app view视图)
View::composer(['layouts/app'], 'App\Http\View\Composers\LayoutsComposer');
}
}
注意
如果合成器里的逻辑有sql查询或者更复杂的业务逻辑,强烈建议不要使用 *,就像这样:
View::composer('*', 'App\Http\View\Composers\LayoutsComposer');
原因:这样会重复执行合成器里的逻辑。执行次数取决于你有多少个视图,包括布局视图。
更多使用案例请参考:https://learnku.com/docs/laravel/6.x/views/5141#b492db
这个功能在strongshop 开源商城也有所应用
Gitee 地址:https://gitee.com/openstrong/strongshop
小伙伴还有什么更好的解决方案?欢迎留言评论!