SlideShare a Scribd company logo
1 of 43
Download to read offline
LivewirevsInertia.js
關於如何選擇全端框架這檔事
LucasYang
ycs77
lucas-yang.vercel.app
喜歡探索有趣的事物。嗜好是看動漫。

目前就讀國立空中大學-管理與資訊學系

使用框架:Laravel/Vue.js/TailwindCSS
現代Web應用架構
伺服器端渲染
(後端渲染)
用戶端渲染
(前端渲染)
經典後端網站架構
路由(後端路由)
+ 資料(ORM)
+ 渲染(後端模板)
= 後端應用
(Laravel,Rails)
「全端網站」的好朋友
SPA時代來臨,網站前後端分離
路由(前端路由)
+ 資料(API)
+ 渲染(前端組件)
= 前端應用
(Vue.js,React,Angular)
以Laravel&Vue舉例,「全端」需包辦以下
開發API(RESTAPI、GraphQL)
管理2個Git專案(SPA&API)
前端路由(vue-router)
身分驗證(JWT…)
狀態管理
CORS
全端:建立現代全端網站很複雜
Laravel的全端解決方案
Livewire Inertia.js
Laravel的全端框架
核心概念:組件
使用語言:PHP&Blade
資料輸入雙向綁定(前後端使用AJAX溝通)
SEO友好
計數器
Livewire 組件 Livewire 視圖
// routes/web.php
use AppHttpLivewireCounter;
Route::get('/', Counter::class);
// app/Http/Livewire/Counter.php
use LivewireComponent;
class Counter extends Component
{
public $count = 0;
public function increment()
{
$this->count++;
}
public function render()
{
return view('livewire.counter');
}
}
<!-- resources/views/livewire/counter.blade.php -->
<div>
<button wire:click="increment">+</button>
<h1>{{ $count }}</h1>
</div>
運作原理
Subsequent Request
Initial Request
Click “+” Button
Browser
Server
<h1>1</h1>
{ count: 1 }
<h1>2</h1>
{ count: 2 }
{ count: 1 }
Visit Page
雙向綁定
Livewire 組件 Livewire 視圖
use LivewireComponent;
class DataBinding extends Component
{
public $name = '';
public $agree = false;
public $languages = ['Laravel', 'Vue.js'];
public function render()
{
return view('livewire.data-binding');
}
}
<div>
<input type="text" wire:model="name">
<input type="checkbox" wire:model="agree">我同意服務條款
@if ($agree)
<div>哈囉~ {{ strtoupper($name) }}</div>
@else
<div>{{ $name }} 請勾選同意服務條款</div>
@endif
<ul>
@foreach ($languages as $language)
<li>{{ $language }}</li>
@endforeach
</ul>
</div>
Polling(輪詢)
<div wire:poll.1s>
{{ now() }}
</div>
即時搜尋
Livewire 組件 Livewire 視圖
use AppModelsLanguage;
use LivewireComponent;
class Search extends Component
{
public $search = '';
protected $queryString = [
'search' => ['except' => ''],
];
public function render()
{
return view('livewire.search', [
'languages' => Language::where('name', 'LIKE',
]);
}
}
<div>
<input type="text" wire:model="search">
<ul>
@foreach ($languages as $language)
<li>{{ $language->name }}</li>
@endforeach
</ul>
</div>
Livewire其他功能
上傳檔案
下載檔案
授權
分頁
載入狀態
離線狀態
Loading狀態
用PHP&Blade寫出JavaScript的效果
BladevsVue?
同時用Blade和Vue來組織視圖
視圖全權交給Vue(View)
<div class="container">
<create-item :data="@json($data)" />
<ul>
@foreach ($items as $item)
<li>{{ $item->content }}</li>
@endforeach
</ul>
</div>
<items-list :data="@json($page)" />
路由(後端路由)
+ 資料(ORM)
渲染(前端組件)
+
=
前端渲染
的
後端應用
Inertia是開發經典後端應用(Laravel,Rails)+前端視圖(Vue.js,React)的方法
後端框架可以使用除了視圖的所有功能,如Router、Controller、
Middleware、身分驗證、授權、EloquentORM……等。
沒有API、沒有前端路由、也沒有SPA應用的複雜性
Inertia定義了一組協議(規則)
提供多個實作Inertia的前端框架套件和後端框架套件
HTTP請求
GET /events/80
HTML響應
GET /api/events/80 {}
JSON響應
HTTP請求
XHR請求
HTTP請求(Inertia)
GET /events/80
HTML響應
Inertia響應
HTTP請求
Inertia請求(XHR)
瀏覽頁面
回傳HTML頁面
基本的CSS和JS
用來啟動SPA應用的<div>根元素

( data-page 屬性中包含InertiaPage物件)
` `
Inertia加載新頁面
點擊<inertia-link>組件,
Inertia會攔截點擊事件並發送一個XHR請求

並回傳InertiaPage物件
然後更新當前頁面的前端組件和瀏覽紀錄
InertiaPage物件
component:前端組件名稱
props:前端組件props(資料)
url:頁面URL
version:當前資產版本
(在Laravel中會自動使用`mix-manifest.json`生成的Hash值作為
資產版本)
發送Inertia請求
import { Inertia } from '@inertiajs/inertia'
Inertia.visit(url, {
method: 'get',
data: {},
replace: false,
preserveState: false,
preserveScroll: false,
only: [],
headers: {},
errorBag: null,
forceFormData: false,
onCancelToken: cancelToken => {},
onCancel: () => {},
onBefore: visit => {},
onStart: visit => {},
onProgress: progress => {},
onSuccess: page => {},
onError: errors => {},
onFinish: visit => {},
})
import { Inertia } from '@inertiajs/inertia'
Inertia.get(url, data, options)
Inertia.post(url, data, options)
Inertia.put(url, data, options)
Inertia.patch(url, data, options)
Inertia.delete(url, options)
InertiaLink
import { Link } from '@inertiajs/inertia-vue3'
<Link href="/">首頁</Link>
// Method:POST / PUT / PATCH / DELETE
<Link href="/logout" method="post" as="button" type="button">登出</Link>
// 連結會渲染成
<button type="button">登出</button>
// post 資料
<Link href="/endpoint" method="post" :data="{ foo: bar }">Save</Link>
// 替換歷史紀錄
<Link href="/" replace>首頁</Link>
// 保持滾動條位置
<Link href="/" preserve-scroll>首頁</Link>
// Partial reloads (局部重載)
<Link href="/users?active=true" :only="['likes_count']">喜歡</Link>
InertiaAdapters(支援的框架)
Inertia官方後端套件
Laravel
Rails
Inertia官方前端套件
Vue.js2/3
React
Svelte
社區開發套件
HelloInertia
路由 VUE 組件
渲染頁面
Prop傳資料
use InertiaInertia;
Route::get('/', function () {
return Inertia::render('Home');
});
// 或
Route::inertia('/', 'Home');
<!-- resources/js/pages/Home.vue -->
<template>
<h1>首頁</h1>
</template>
use InertiaInertia;
Route::get('/about', function () {
return Inertia::render('About', [
'name' => 'Lucas',
]);
});
<!-- resources/js/pages/About.vue -->
<template>
<h1>關於</h1>
<div>你好~ 我是 {{ name }}</div>
</template>
<script>
export default {
props: {
name: String,
},
}
</script>
Layout
<template>
<div>...</div>
</template>
<script>
import Layout from '@/Layout.vue'
export default {
layout: Layout,
...
}
</script>
會員登入
use InertiaInertia;
class LoginController extends Controller
{
public function loginView()
{
return Inertia::render('Auth/Login');
}
public function login(Request $request)
{
// Auth::attempt()...
}
public function logout(Request $request)
{
// Auth::logout()...
}
}
會員登入
<template>
<h1>會員登入</h1>
<form @submit.prevent="form.post('/login')">
<div class="input-group">
<label>E-mail:</label>
<input type="text" v-model="form.email">
<div v-if="form.errors.email" class="invalid">
{{ form.errors.email }}
</div>
</div>
<div class="input-group">
<label>密碼:</label>
<input type="password" v-model="form.password">
</div>
<button>送出</button>
</form>
...
</template>
<script>
import { useForm } from '@inertiajs/inertia-vue3'
export default {
// ...
setup() {
const form = useForm({
email: '',
password: '',
})
return { form }
},
}
</script>
留言板-留言列表
跟資料庫拿資料
class CommentController extends Controller
{
public function index()
{
return Inertia::render('Comments', [
'comments' => Comment::all()
->transform(fn (Comment $comment) => [
'id' => $comment->id,
'name' => $comment->name,
'content' => $comment->content,
'created_at' => $comment
->created_at
->format('Y/m/d H:i'),
]),
]);
}
}
<template>
<h1>留言</h1>
...
<ul>
<li v-for="comment in comments">
<h2>姓名:{{ comment.name }}</h2>
<div>{{ comment.created_at }}</div>
<div>內容:{{ comment.content }}</div>
</li>
</ul>
</template>
<script>
export default {
props: {
comments: Array,
},
// ...
}
</script>
留言板-表單送出
<template>
<h1>留言</h1>
<form @submit.prevent="storeComment">
<div class="input-group">
<label>姓名:</label>
<input type="text" v-model="form.name">
<div v-if="form.errors.name" class="invalid">
{{ form.errors.name }}
</div>
</div>
<div class="input-group">
<label>留言:</label>
<textarea v-model="form.content"></textarea>
<div v-if="form.errors.content" class="invalid">
{{ form.errors.content }}
</div>
</div>
<button>送出</button>
</form>
...
</template>
<script>
import { useForm } from '@inertiajs/inertia-vue3'
export default {
// ...
setup() {
const form = useForm({
name: '',
content: '',
})
const storeComment = () => {
form.post('/comments', {
onSuccess: () => form.reset(),
})
}
return { form, storeComment }
},
}
</script>
留言板-表單送出
class CommentController extends Controller
{
public function store(Request $request)
{
$data = $request->validate([
'name' => 'required',
'content' => 'required',
], [
'name.required' => '請輸入姓名',
'content.required' => '請輸入留言',
]);
Comment::create($data);
return back();
}
}
錯誤處理
InertiaDemo
官方介紹|PingCRM|GitHub
SSR(服務端渲染)-優化SEO 測試階段
1. 發送請求進入後端框架-Laravel
2. Inertia將Page物件發送給本地SSRServer,

使用Node.js將當前頁面的前端組件渲染為HTML-Node.js
3. 將HTML插入到響應中並回傳給用戶
4. SSR模式下啟動前端框架-vue-server-renderer

(Vue、React、Svelte都有處理SSR的工具)
5. SSR渲染只會在進頁面時執行,之後就會以SPA模式運作
PingCRM-SSRDemo
TALLStack
TailwindCSS+Alpine.js+Laravel+Livewire
VILTStack
Vue.js+Inertia.js+Laravel+TailwindCSS
LivewireorInertia
會員登入/註冊
E-mail驗證
雙因素身分驗證
登入Session管理
APItoken(LaravelSanctum)
團隊功能
LivewirevsInertia.js
Livewire Inertia.js
框架 Laravel 支援Inertia的框架
視圖(View) Blade、PHP、Alpine.js 前端框架Vue、React…
SEO 易 難
總結 用PHP寫出JavaScript的效果 前後端框架的膠水
Blade Livewire
Vue.js Inertia.js
參考資料
Livewire官網
Inertia.js官網
LaravelJetstream官網
TALLstack
VILTStack
前端渲染的後端應用-用Inertia.js拉近Laravel和Vue.js的距離

More Related Content

What's hot

View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎Shengyou Fan
 
一拍一产品背后的故事(React实战)
一拍一产品背后的故事(React实战)一拍一产品背后的故事(React实战)
一拍一产品背后的故事(React实战)Kejun Zhang
 
使用 laravel 的前與後
使用 laravel 的前與後使用 laravel 的前與後
使用 laravel 的前與後Shengyou Fan
 
Package 安裝與使用
Package 安裝與使用Package 安裝與使用
Package 安裝與使用Shengyou Fan
 
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架Justin Lin
 
開發環境建置
開發環境建置開發環境建置
開發環境建置Shengyou Fan
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 SeedingShengyou Fan
 
Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1modou li
 
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染Sheng-Han Su
 
Laravel - 系統全攻略(續)
Laravel - 系統全攻略(續)Laravel - 系統全攻略(續)
Laravel - 系統全攻略(續)Vincent Chi
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎Shengyou Fan
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練Joseph Chiang
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 SeedingShengyou Fan
 

What's hot (20)

View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
CRUD 綜合應用
CRUD 綜合應用CRUD 綜合應用
CRUD 綜合應用
 
一拍一产品背后的故事(React实战)
一拍一产品背后的故事(React实战)一拍一产品背后的故事(React实战)
一拍一产品背后的故事(React实战)
 
使用 laravel 的前與後
使用 laravel 的前與後使用 laravel 的前與後
使用 laravel 的前與後
 
CRUD 綜合運用
CRUD 綜合運用CRUD 綜合運用
CRUD 綜合運用
 
CRUD 綜合運用
CRUD 綜合運用CRUD 綜合運用
CRUD 綜合運用
 
使用 Controller
使用 Controller使用 Controller
使用 Controller
 
Package 安裝與使用
Package 安裝與使用Package 安裝與使用
Package 安裝與使用
 
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
 
Route 機制
Route 機制Route 機制
Route 機制
 
How tovuejs
How tovuejsHow tovuejs
How tovuejs
 
開發環境建置
開發環境建置開發環境建置
開發環境建置
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 Seeding
 
Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1
 
Route路由控制
Route路由控制Route路由控制
Route路由控制
 
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
 
Laravel - 系統全攻略(續)
Laravel - 系統全攻略(續)Laravel - 系統全攻略(續)
Laravel - 系統全攻略(續)
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 Seeding
 

Similar to 2021.laravelconf.tw.slides3

用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Servicesjavatwo2011
 
Laravel II - Developer Student Clubs NCU.pdf
Laravel II - Developer Student Clubs NCU.pdfLaravel II - Developer Student Clubs NCU.pdf
Laravel II - Developer Student Clubs NCU.pdfNCUDSC
 
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
從 Web Site 到 Web Application,從 Web Services 到 Mobile ServicesKuo-Chun Su
 
Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務
Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務
Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務Mu-Fan Teng
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎Shengyou Fan
 
前端MVC之backbone
前端MVC之backbone前端MVC之backbone
前端MVC之backboneJerry Xie
 
Non-MVC Web Framework
Non-MVC Web FrameworkNon-MVC Web Framework
Non-MVC Web FrameworkFred Chien
 
Java Web动态图表编程
Java Web动态图表编程Java Web动态图表编程
Java Web动态图表编程yiditushe
 
W3CTech美团react专场-Thinking in React
W3CTech美团react专场-Thinking in ReactW3CTech美团react专场-Thinking in React
W3CTech美团react专场-Thinking in React美团点评技术团队
 
Underscore
UnderscoreUnderscore
Underscorecazhfe
 
Exam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsExam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsChieh Lin
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoloadjay li
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型Jackson Tian
 
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 ServletServlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 ServletJustin Lin
 
2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swttka
 
Terracotta And Continuent Based Clustering Architecture
Terracotta And Continuent Based Clustering ArchitectureTerracotta And Continuent Based Clustering Architecture
Terracotta And Continuent Based Clustering ArchitectureTarget Source
 
Rest Ruby On Rails
Rest Ruby On RailsRest Ruby On Rails
Rest Ruby On Railsshaokun
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型裕波 周
 

Similar to 2021.laravelconf.tw.slides3 (20)

用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
 
Laravel II - Developer Student Clubs NCU.pdf
Laravel II - Developer Student Clubs NCU.pdfLaravel II - Developer Student Clubs NCU.pdf
Laravel II - Developer Student Clubs NCU.pdf
 
Jsp
JspJsp
Jsp
 
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
 
Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務
Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務
Mopcon2014 - 使用 Sinatra 結合 Ruby on Rails 輕鬆打造完整 Full Stack 網站加 API Service服務
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
Vue ithome
Vue ithome Vue ithome
Vue ithome
 
前端MVC之backbone
前端MVC之backbone前端MVC之backbone
前端MVC之backbone
 
Non-MVC Web Framework
Non-MVC Web FrameworkNon-MVC Web Framework
Non-MVC Web Framework
 
Java Web动态图表编程
Java Web动态图表编程Java Web动态图表编程
Java Web动态图表编程
 
W3CTech美团react专场-Thinking in React
W3CTech美团react专场-Thinking in ReactW3CTech美团react专场-Thinking in React
W3CTech美团react专场-Thinking in React
 
Underscore
UnderscoreUnderscore
Underscore
 
Exam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsExam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development Fundamentals
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoload
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
 
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 ServletServlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
 
2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt
 
Terracotta And Continuent Based Clustering Architecture
Terracotta And Continuent Based Clustering ArchitectureTerracotta And Continuent Based Clustering Architecture
Terracotta And Continuent Based Clustering Architecture
 
Rest Ruby On Rails
Rest Ruby On RailsRest Ruby On Rails
Rest Ruby On Rails
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
 

More from LiviaLiaoFontech

More from LiviaLiaoFontech (9)

2021laravelconftwslides12
2021laravelconftwslides122021laravelconftwslides12
2021laravelconftwslides12
 
2021laravelconftwslides11
2021laravelconftwslides112021laravelconftwslides11
2021laravelconftwslides11
 
2021laravelconftwslides9
2021laravelconftwslides92021laravelconftwslides9
2021laravelconftwslides9
 
2021laravelconftwslides8
2021laravelconftwslides82021laravelconftwslides8
2021laravelconftwslides8
 
2021laravelconftwslides6
2021laravelconftwslides62021laravelconftwslides6
2021laravelconftwslides6
 
2021laravelconftwslides4
2021laravelconftwslides42021laravelconftwslides4
2021laravelconftwslides4
 
2021.laravelconf.tw.slides5
2021.laravelconf.tw.slides52021.laravelconf.tw.slides5
2021.laravelconf.tw.slides5
 
2021.laravelconf.tw.slides2
2021.laravelconf.tw.slides22021.laravelconf.tw.slides2
2021.laravelconf.tw.slides2
 
2021.laravelconf.tw.slides1
2021.laravelconf.tw.slides12021.laravelconf.tw.slides1
2021.laravelconf.tw.slides1
 

2021.laravelconf.tw.slides3