結論
『値が変動する物』はプロパティに宣言
『値が変動しない物』はviewに渡す
そもそもの違い
プロパティで宣言してようがViewに渡そうがBlade内では同じように扱えますが全然違います。
プロパティ
プロパティで宣言した変数はJsonでフロントエンドとバックエンドで同期を行います。
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Sample0907 extends Component
{
public $hoge = 'hogeValue';
public $huga = 'hugaValue';
.......
Render内でviewに渡す
HTMLを生成する時にviewに渡しているだけです。
コントローラーなどで変数をbladeに渡しているのと同じです。
return view('hoge',compact('hoge'))
プロパティで宣言する時の注意点
配列が挿入順に回らない場合がある
例えば、このように配列をプロパティとして宣言するとします
class Sample0907 extends Component
{
public $array = [];
public function mount()
{
$array = [
2 => '1番目',
0 => '2番目',
1 => '3番目'
];
$this->array = $array;
}
Bladeでdd()
してみます。
はい、勝手にソートされてます。
Livewireのソースを調べてみると、ソートしている箇所を見つけました。
$itemsWithNumericKeys = array_filter($value, function ($key) {
return is_numeric($key);
}, ARRAY_FILTER_USE_KEY);
ksort($itemsWithNumericKeys);
ですので、セレクトボックスの項目などを
<select name="name" id="name">
@foreach($array as $key => $value)
<option value="{{ $key }}">{{ $value }}</option>
@endforeach
</select>
のように書きたい場合、DBから取得したものを並べたい順にして生成しても
キーの連番に並び替えられます。
オブジェクトは配列に変換される
このようにオブジェクト群を内包した配列と、入力用の変数を1つ用意します。
class Sample0907 extends Component
{
public $array = [];
public $text;
public function mount()
{
$array = [
(object)['id' => 1, 'name' => '田中'],
(object)['id' => 2, 'name' => '源田']
];
$this->array = $array;
}
Bladeも書きます
<div>
@foreach($array as $key => $value)
{{ $value->name }}<br/>
@endforeach
<input type="text" wire:model="text" />
</div>
初回アクセスは問題ありません。
はい、死にました。
どうやらLaravelのRequestの中でjsonが強制的に配列になるっぽいです
@hulkurLivewire は stdObjects を再水和できないため、そのような動作が発生することを期待しています。そのため、それらは配列として終了します。その理由は、Laravel リクエスト オブジェクトです。json_decode を実行すると、json オブジェクトが強制的に配列になります。この問題を参照してくださいlaravel/framework#443
詳しくコードを追えてる訳では無いのですが
Modelオブジェクトや、Model群を内包しているコレクションは特別扱いされてるみたいです。
以下のコードには記載されてませんがcarbonオブジェクトもです。
src/HydrationMiddleware/HydratePublicProperties.php
protected static function dehydrateModel($value, $property, $response, $instance)
{
$serializedModel = $value instanceof QueueableEntity && ! $value->exists
? ['class' => get_class($value)]
: (array) (new static)->getSerializedPropertyValue($value);
// Deserialize the models into the "meta" bag.
data_set($response, 'memo.dataMeta.models.'.$property, $serializedModel);
$filteredModelData = static::filterData($instance, $property);
// Only include the allowed data (defined by rules) in the response payload
data_set($response, 'memo.data.'.$property, $filteredModelData);
}
protected static function dehydrateModels($value, $property, $response, $instance)
{
$serializedModel = (array) (new static)->getSerializedPropertyValue($value);
// Deserialize the models into the "meta" bag.
data_set($response, 'memo.dataMeta.modelCollections.'.$property, $serializedModel);
$filteredModelData = static::filterData($instance, $property);
// Only include the allowed data (defined by rules) in the response payload
data_set($response, 'memo.data.'.$property, $filteredModelData);
}
ですので、livewireでstdclassをプロパティとして扱うのはやめておきましょう。
プロパティをカスタムしたい場合
ドキュメントに記載されてます。