feat: The merged attributes in the view component support attributes other than 'class'.

This commit is contained in:
nfangxu 2020-12-31 10:59:17 +08:00 committed by 李铭昕
parent 6f3351a744
commit 414e4ceb01
9 changed files with 113 additions and 20 deletions

View File

@ -692,6 +692,28 @@ class ConfigProvider
</div>
```
默认情况下,只会合并 `class` 属性,其他属性将会直接进行覆盖,会出现如下情况:
```blade
// 定义
<div {{ $attributes->merge(['class' => 'alert alert-'.$type, 'other-attr' => 'foo']) }}>{{ $message }}</div>
// 使用
<x-alert type="error" :message="$message" class="mb-4" other-attr="bar"/>
// 呈现
<div class="alert alert-error mb-4" other-attr="bar"><!-- $message 变量的内容 --></div>
```
如上述情况,需要将 `other-attr` 属性也合并的话, 可以使用一下方式:
```blade
// 定义
<div {{ $attributes->merge(['class' => 'alert alert-'.$type, 'other-attr' => 'foo'], true) }}>{{ $message }}</div>
// 使用
<x-alert type="error" :message="$message" class="mb-4" other-attr="bar"/>
// 呈现
<div class="alert alert-error mb-4" other-attr="foo bar"><!-- $message 变量的内容 --></div>
```
#### 插槽
通常,你需要通过 `slots` 向组件传递附加内容。 假设我们创建的 `alert` 组件具有以下标记:

View File

@ -220,7 +220,7 @@ class ComponentAttributeBag implements ArrayAccess, Htmlable, IteratorAggregate
*
* @return static
*/
public function merge(array $attributeDefaults = [])
public function merge(array $attributeDefaults = [], bool $forceMerge = false)
{
$attributes = [];
@ -233,9 +233,8 @@ class ComponentAttributeBag implements ArrayAccess, Htmlable, IteratorAggregate
}, $attributeDefaults);
foreach ($this->attributes as $key => $value) {
if ($key !== 'class') {
if (! $forceMerge && $key !== 'class') {
$attributes[$key] = $value;
continue;
}

View File

@ -19,8 +19,6 @@ use Hyperf\Event\EventDispatcher;
use Hyperf\Event\ListenerProvider;
use Hyperf\Utils\ApplicationContext;
use Hyperf\View\Mode;
use Hyperf\ViewEngine\Compiler\BladeCompiler;
use Hyperf\ViewEngine\Compiler\CompilerInterface;
use Hyperf\ViewEngine\Component\DynamicComponent;
use Hyperf\ViewEngine\ConfigProvider;
use Hyperf\ViewEngine\Contract\FactoryInterface;
@ -29,6 +27,8 @@ use Hyperf\ViewEngine\Contract\ViewInterface;
use Hyperf\ViewEngine\Factory\FinderFactory;
use Hyperf\ViewEngine\HyperfViewEngine;
use HyperfTest\ViewEngine\Stub\Alert;
use HyperfTest\ViewEngine\Stub\AlertAttributeMerge;
use HyperfTest\ViewEngine\Stub\AlertAttributeMergeForce;
use HyperfTest\ViewEngine\Stub\AlertSlot;
use PHPUnit\Framework\TestCase;
use Psr\EventDispatcher\EventDispatcherInterface;
@ -65,6 +65,8 @@ class BladeTest extends TestCase
'components' => [
'alert' => Alert::class,
'alert-slot' => AlertSlot::class,
'alert-attribute-merge' => AlertAttributeMerge::class,
'alert-attribute-merge-force' => AlertAttributeMergeForce::class,
'dynamic-component' => DynamicComponent::class,
],
'namespaces' => [
@ -139,31 +141,23 @@ class BladeTest extends TestCase
public function testComponent()
{
/** @var BladeCompiler $compiler */
$compiler = ApplicationContext::getContainer()
->get(CompilerInterface::class);
$compiler->component(Alert::class, 'alert');
$compiler->component(AlertSlot::class, 'alert-slot');
$this->assertSame('success', trim((string) view('simple_8', ['message' => 'success'])));
$this->assertSame('success', trim((string) view('simple_9', ['message' => 'success'])));
}
public function testDynamicComponent()
{
/** @var BladeCompiler $compiler */
$compiler = ApplicationContext::getContainer()
->get(CompilerInterface::class);
$compiler->component(Alert::class, 'alert');
$compiler->component(AlertSlot::class, 'alert-slot');
$this->assertSame('ok', trim((string) view('simple_11', ['componentName' => 'alert', 'message' => 'ok'])));
}
public function testComponetAutoload()
public function testComponentAutoload()
{
$this->assertSame('success', trim((string) view('simple_12', ['message' => 'success'])));
}
public function testComponentMergeAttribute()
{
$this->assertSame('<div class="alert alert-error mb4" style="height:50px">success</div>', trim((string) view('simple_13', ['message' => 'success'])));
$this->assertSame('<div class="alert alert-error mb4" style="background-color:red; height:50px">success</div>', trim((string) view('simple_14', ['message' => 'success'])));
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\ViewEngine\Stub;
use Hyperf\Utils\ApplicationContext;
use Hyperf\ViewEngine\Component\Component;
use Hyperf\ViewEngine\Contract\FactoryInterface;
class AlertAttributeMerge extends Component
{
public $message;
public $type;
public function __construct($message, $type)
{
$this->message = $message;
$this->type = $type;
}
public function render()
{
$factory = ApplicationContext::getContainer()
->get(FactoryInterface::class);
return $factory->make('components.alert-3');
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\ViewEngine\Stub;
use Hyperf\Utils\ApplicationContext;
use Hyperf\ViewEngine\Component\Component;
use Hyperf\ViewEngine\Contract\FactoryInterface;
class AlertAttributeMergeForce extends Component
{
public $message;
public $type;
public function __construct($message, $type)
{
$this->message = $message;
$this->type = $type;
}
public function render()
{
$factory = ApplicationContext::getContainer()
->get(FactoryInterface::class);
return $factory->make('components.alert-4');
}
}

View File

@ -0,0 +1 @@
<div {{ $attributes->merge(["class" => 'alert alert-' . $type, "style" => "background-color:red;"]) }}>{{ $message ?? "alert" }}</div>

View File

@ -0,0 +1 @@
<div {{ $attributes->merge(['class' => 'alert alert-' . $type, "style" => "background-color:red;"], true) }}>{{ $message ?? "alert" }}</div>

View File

@ -0,0 +1 @@
<x-alert-attribute-merge type="error" class="mb4" style="height:50px" :message="$message" />

View File

@ -0,0 +1 @@
<x-alert-attribute-merge-force type="error" class="mb4" style="height:50px" :message="$message" />