嵌套元件(Nesting Components),在 Vue.js 中是很普遍的用法,可以在父元件赋予数值给子元件进而改变子元件显示的资料。实作中通常会将可重复的内容与主画面分成父子页面,让程序码看起来更简洁更好维护。但在 Livewire 却有些使用上的限制:
子元件虽然可以接收来自父元件的参数,但不能像 Vue 一样即时渲染子元件的内容。
即:透过在元件元素传值的方式只能渲染第一次的值
首先是父元件
<?php
namespace App\Http\Livewire\Example;
use Livewire\Component;
class Day10 extends Component
{
public $menu_type;
public function render()
{
return view('livewire.example.day10');
}
}
<div class="text-center">
<h2>Day10: 嵌套元件</h2>
<div class="mb-5">
<button class="ui button" wire:click="$set('menu_type', '茶')">茶</button>
<button class="ui button" wire:click="$set('menu_type', '果汁')">果汁</button>
<button class="ui button" wire:click="$set('menu_type', '咖啡')">咖啡</button>
</div>
<h5>目前选的是{{ $menu_type }}</h5>
@if($menu_type)
@livewire('example.day10-card', ['menu' => $menu_type])
@endif
</div>
以及子元件
<?php
namespace App\Http\Livewire\Example;
use Livewire\Component;
class Day10Card extends Component
{
public $menu;
public function render()
{
return view('livewire.example.day10-card');
}
}
<div class="flex justify-center">
<div class="rounded shadow-md bg-grey-50 border-2 w-96 p-4">
<h1>{{ $menu }}的菜单</h1>
<p>...</p>
</div>
</div>
在这个范例中,我们设想了一个 电子菜单 的功能,点击上方不同的类别,底下的菜单就会跟着改变。这里我们透过按钮wire:click()
与之前提到的魔术方法$set()
直接去修改 $menu_type
的值,并在$menu_type
有值後显示底下的子元件day10-card
。
如果是照着 Vue.js 的运行方式,当我们每次更改 $menu_type
的同时,也会对子元件所传入的 $menu
一起做更改,但演示结果并不然。如页面显示,我们在父元件能清楚看到 $menu_type
有确实的更改,但子元件上印出的却不为所动。
简单的解决方式则可以在父元件中透过 Lifecycle Hooks 的 updatingFoo
在 $menu_type
有改变时透过 $emit
传递最新的数据给子元件中负责更新 $menu
的函式,如此一来不用动到前端的程序码也能在後端进行资料的同步。
由於只要在 $menu_type
有更改时才需要动作,这边就可以用 updatedMenuType
来限缩画面更新时的事件。而 $emit
因为是 全画面的Livewire元件 都会收到,为了避免误传到其他元件中同名的监听函式,所以这里保险一点使用了 $emitTo
并带上 目标元件 跟 函式名 及 数值。
<?php
namespace App\Http\Livewire\Example;
use Livewire\Component;
class Day10 extends Component
{
public $menu_type;
public function render()
{
return view('livewire.example.day10');
}
/*
加上 Lifecycle Hooks 的 updated
*/
public function updatedMenuType($value)
{
$this->emitTo('example.day10-card', 'updateMenu', $value);
}
}
在子元件的部分 必须 建立一个 $listeners
去监听 $emit
事件,并导向本地的函式。
在上面的父元件我们会$emit
到 updateMenu
这个名称,并对应到本地的 setMenu()
来改变子元件中 $menu
的值,进而改变页面上的显示。
<?php
namespace App\Http\Livewire\Example;
use Livewire\Component;
class Day10Card extends Component
{
public $menu;
public function render()
{
return view('livewire.example.day10-card');
}
/*
加上 updateMenu 事件的监听,与对应的更新函式
*/
protected $listeners = ['updateMenu' => 'setMenu'];
public function setMenu($value)
{
$this->menu = $value;
}
}
本文同步刊登於个人技术部落格,有兴趣关注更多 Kubernetes、DevOps 相关资源的读者,请...
前言 昨天讲过了远古时代的记忆体管理,跟後续为了解决最古老的记忆体管理所引发的问题而接着有的分段管理...
在实作的过程中,原本想把这篇省略掉,但在往後的实作中,偶而会利用到这些模块与知识,放在这篇,之後文中...
用键盘输入讯息,对年轻人或许稀松平常,但对长者而言,使用语音的方式或许更轻松。所以除了画面字体放大外...
在前几期,把AR装置的发展过程大略的描述了一下,从厚重的头戴式装置到可供个人购买的AR眼镜,但这中间...