具有动态属性的 Laravel 组件

问题描述

我正在使用 Laravel 并使用相关联的 PHP 类创建组件。我将以我的用例为例:

视图/P.PHP

class P {

    public function render() {
        return view('views.p');
    }
}

resources/views/p.blade.PHP

<p class="pb-4"></p>

上面我使用 Tailwind 实用程序类来添加填充底部

现在,我可以在我的应用程序中使用这个组件和类似的组件。例如:

some.blade.PHP

<x-h1>Title</x-h1>
<x-p>Hello world</x-p>

请注意,我还包含了一个 <x-h1>。这也可以有类似的底部填充。

我希望能够使用这样的属性删除填充:

some.blade.PHP

<x-h1 no-margin>Title</x-h1>
<x-p no-margin>Hello world</x-p>

但现在我需要定义在两个 PHP 类中执行此操作的逻辑。我的逻辑包含在父类或特征中,但我遇到的问题是,对于每个组件,我需要在构造函数中定义属性,如下所示:

视图/P.PHP

class P {

    use noMarginModifier;

    public $noMargin;

    public function __constructor($noMargin = false) {
        $this->noMargin = $noMargin;
        // do something from noMarginModifier trait
    }

    public function render() {
        return view('views.p');
    }
}

视图/H1.PHP

class H1 {

    use noMarginModifier;

    public $noMargin;

    public function __constructor($noMargin = false) {
        $this->noMargin = $noMargin;
        // do something from noMarginModifier trait
    }

    public function render() {
        return view('views.h1');
    }
}

对于这个例子来说是可以的,但是,我很快就会扩展属性数量,可能有 no-marginhiglight 等等。

我能想到的唯一方法是在一个属性中包含所有属性,如下所示:

视图/H1.PHP

class H1 {

    use modifier;

    public $modifiers;

    public function __constructor($modifiers = []) {
        $this->modifiers = $modifiers;
        // do something with modifiers
    }

    public function render() {
        return view('views.h1');
    }
}

这个解决方案的唯一问题是我必须像这样使用组件:

<x-h1 :modifiers="['no-margin' => true]"></h1>

这使得写一个没有边距的标题有点麻烦。

我希望能够从组件定义中自动获取属性

解决方法

我有一个解决方案,但由于提到的注意事项,感觉有点古怪,就是访问 Laravel docs 中提到的组件类中的属性和插槽。

这导致了一个类:

视图/H1.php

class H1 {

    use modifier;

    public function render()
        {
            return function (array $data) {            
                // no-margin exists here
                $data['attributes']['no-margin'];
                // do something with modifiers
                return 'components.h1';
            };
        }
    }

但是,我在模板中看到的警告是:

resources/vies/h1.blade.php

{{ $attributes->merge(['no-margin' => 'anotherValue']) }}

当我合并上述属性时。然后更改不会反映在模板中。