Laravel 使用视图合成器 view composer 实现视图变量共享

通常我们这样做来实现视图变量全局共享

<?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

小伙伴还有什么更好的解决方案?欢迎留言评论!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值