本來是沒打算分成兩天的。但第一天放入了程式碼讓文章看起來比較冗長,所以只好拆兩天啦!今天一樣也是 嵌套元件 Nesting Components 的部分。昨天在演示了一般父、子元件的基礎用法,那今天就來演示最常見的嵌套元件用法吧!!
無論是透過 PHP 或是 Vue 在做頁面時,遇到大量重複的資料要顯示在頁面上,像是鐵人賽的文章列表。通常都會將顯示資料的區塊寫成一個元件,再藉由迴圈重複刷出該元件來達成頁面上的顯示。當然這在 Livewire 中也是小菜一碟!!
@foreach($articles as $article)
@livewire('card', ['title' => $article->title], key($article->id))
@endforeach
@foreach($articles as $article)
<livewire:card : title ="$article->title" :wire:key="$article->id">
@endforeach
key
必需要有!雖然在 Livewire 中就算 key
沒給也不會報錯,但如果你有要對資料做變動就一定要有 key
。則在資料變動時會導致 DOM 發生無法意料的錯誤,例如要刪除某筆資料就會造成畫面渲染的錯誤!!
而有了 key
之後也要避免 key
的名稱重複,如同 HTML 中的 id
一樣,因此在給 key
的時候前面可以加上一些字串當作前輟好來避免重複使用同樣名字的key,官方文件也有舉幾個例子:
<!-- user-profile component -->
<div>
// Bad
<livewire:user-profile-one :user="$user" :wire:key="$user->id">
<livewire:user-profile-two :user="$user" :wire:key="$user->id">
// Good
<livewire:user-profile-one :user="$user" :wire:key="'user-profile-one-'.$user->id">
<livewire:user-profile-two :user="$user" :wire:key="'user-profile-two-'.$user->id">
</div>
那當然今天也會有範例給大家試試,有時間的話不妨把範例中的 key
拿掉試試看會發生什麼事!!
今天的範例是做一個文章列表, DEMO網址:
在父元件的部分會有一個變數來放文章的內容,由於不使用資料庫進行實作,因此用 Array 放假資料代替。並在前端畫面透過 @foreach
刷出多的子元件
<?php
namespace App\Http\Livewire\Example;
use Livewire\Component;
class Day11 extends Component
{
public $articles = array(
[
'id' => 1,
'title' => 'Day 01 | 前言與賽程',
'content' => '從 2018 年介紹 Vue 的 UI Framework — Quasar ,到前年的 LINE Bot。 每年鐵人賽都剛好是工作最繁忙的下半年,希望下次能辦...',
'url' => 'https://ithelp.ithome.com.tw/articles/10259642',
],
[
'id' => 2,
'title' => 'Day 02 | Laravel Livewire 基本介紹',
'content' => 'Livewire 是 Laravel 的全端框架,能建立像 Vue 一樣的動態頁面的同時又能保有 Laravel 原有的特性。除此之外在 SEO 方面仍跟原本...',
'url' => 'https://ithelp.ithome.com.tw/articles/10259945',
],
[
'id' => 3,
'title' => 'Day 03 | 透過指令建立元件',
'content' => '安裝並部署 Livewire 的步驟沒有很多,照著做不用三分鐘就能完成囉!今天一樣是照著官方文件帶大家做一次囉~ 安裝 Livewire 官方文件 首先要先安裝...',
'url' => 'https://ithelp.ithome.com.tw/articles/10260438',
],
);
public function render()
{
return view('livewire.example.day11');
}
public function clearArticle($index)
{
unset($this->articles[$index]);
}
}
<div class="text-center p-5">
<h2>Day11: 嵌套元件(二)</h2>
@foreach($articles as $article)
@livewire('example.day11-card', ['article' => $article], key('article-2021-' . $article['id']))
@endforeach
<div class="my-5">
<button class="ui button" wire:click="clearArticle(1)" >刪除 Day2</button>
</div>
</div>
子元件就是一張顯示來自父元件資料的卡片,即為顯示每篇文章的畫面。
<?php
namespace App\Http\Livewire\Example;
use Livewire\Component;
class Day11Card extends Component
{
public $article;
public function render()
{
return view('livewire.example.day11-card');
}
}
<div class="flex justify-center mt-5">
<div class="rounded shadow-md bg-grey-50 border-2 w-3/6 p-4 pl-8 text-left">
<h3>
<a class="text-black" href="{{ $article['url'] }}" target="_blank">
{{ $article['title'] }}
</a>
</h3>
<div class="text-gray-500">
{{ $article['content'] }}
</div>
</div>
</div>