หวนคืนนึกถึง Php ที่คุ้นเคย Laravel ที่ยังเคยใช้งานเมื่อยังมีแค่เวอร์ชั่น 7 แค่นั้น และปัจจุบันมีถึง 10 เวอร์ชั่นเข้าไปแล้ว มีเหตุให้ต้องคิดถึงเครื่องมือเหล่านี้ พอดีได้เริ่มติดตั้ง และทดลองใช้งาน เลยอยากที่จะบันทึกไว้เป็นไกไลด์สำหรับใช้ทำในครั้งถัด ๆ ไป เอาแบบพอใช้งานได้ โดย
- Laravel 9 ขึ้นไปเพราะต้องการกำหนด PHP เวอร์ชั่นต่ำคือ PHP8 ในการรันโปรเจคนี้
- Vue3 เพราะความรวดเร็วในการพัฒนา (เลือกที่ตัวเองถนัด)
- Inertia.js สารารถสร้างแอป React, Vue และ Svelte หน้าเดียวที่ทันสมัยโดยใช้การกำหนดเส้นทางฝั่งเซิร์ฟเวอร์แบบคลาสสิก ใช้งานได้กับแบ็กเอนด์ใดๆ ยังสามารถใช้งานกับ Laravel ได้อย่างดีเยี่ยม
- Bootstrap เลือกใช้เพราะความคุ้นเคย
เมื่อทราบเหตุผล เรามาเริ่มกันเลยดีกว่า
เริ่มติดตั้งเฟรมเวิร์ค และไลบารี่ ต่าง ๆ ที่จำเป็น
เริ่มต้นให้ทำการติดตั้ง PHP สำหรับใช้ในการรัน Laravel โปรเจค และอย่าลืมติดตั้ง NodeJs และ NPM ให้พร้อม
- ติดตั้ง PHP เวอร์ชั่น 8 ขึ้นไป (mac os ก็ติดตั้งด้วย `brew install [email protected]`, window os ติดตั้งตากที่นี่ https://www.php.net/manual/en/install.windows.php)
- ติดตั้ง NodeJS และ NPM เป็นเวอร์ชั่นล่าสุดไปเลย
- ติดตั้ง Composer
หลังจากเตรียมพวกซอพแวร์หลัก เรียบร้อยถึงเวลาไปสร้างโปรเจคกัน
- เริ่มต้นที่ Laravel
composer create-project laravel/laravel:^9.0 new-project-name
- ติดตั้ง Inertia เพิ่มเติม และสร้าง Inertia middleware
composer require inertiajs/inertia-laravel
php artisan inertia:middleware
จะได้ไฟล์ HandleInertiaRequests.php อยู่ภายใต้ app/Http/Middleware ให้ทำการเพิ่มคำสั่ง
'web' => [
// ...
\App\Http\Middleware\HandleInertiaRequests::class,
],
เข้าไปที่ไฟล์ app/Http/Kernel.php
ติดตั้งแพ็คเกต ด้วย NPM
- Inertia และ Vue3
npm install @inertiajs/vue3 vue-loader vue --save-dev
- bootstrap 5
npm install @popperjs/core bootstrap --save-dev
- laravel-mix เพื่อเอาไว้ compile minify js, css
npm install laravel-mix --save-dev
- เกี่ยว css
npm install postcss postcss-import --save-dev
- แก้ไขปรับแต่ง scripts ในไฟล์ package.json
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
- หน้าตาของไฟล์ package.json ทั้งหมด
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"@popperjs/core": "^2.9.2",
"autoprefixer": "^10.4.16",
"axios": "^1.1.2",
"bootstrap": "^5.3.2",
"laravel-mix": "^6.0.11",
"lodash": "^4.17.19",
"postcss": "^8.4.31",
"postcss-import": "^12.0.1",
"vue": "^3.2.36",
"vue-loader": "^17.3.0",
"@inertiajs/vue3": "^1.0.13"
},
"dependencies": {
"mix": "0.0.1"
}
}
เพิ่ม และแก้ไขโค๊ด ส่วนการตั้งค่าของ webpack.mix.js
- ให้ทำการสร้างไฟล์ /webpack.mix.js
const path = require("path");
const mix = require("laravel-mix");
// Rezolve Ziggy
mix.alias({
ziggy: path.resolve("vendor/tightenco/ziggy/dist/vue"),
});
// Build files
mix.js("resources/js/app.js", "public/js")
.vue({ version: 3 })
.webpackConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "resources/js"),
},
},
})
.extract()
.postCss("resources/css/app.css", "public/css", []) //require("bootstrap")
.version();
- สร้างไฟล์ /resources/views/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@routes
<link href="{{ asset(mix('css/app.css')) }}" rel="stylesheet">
<script src="{{ asset(mix('js/manifest.js')) }}" defer></script>
<script src="{{ asset(mix('js/vendor.js')) }}" defer></script>
<script src="{{ asset(mix('js/app.js')) }}" defer></script>
@inertiaHead
</head>
<body>
@inertia
</body>
</html>
- แก้ไขไฟล์ /resources/js/app.js
import { createApp, h } from "vue";
import { createInertiaApp, Link, Head } from "@inertiajs/vue3";
import { ZiggyVue } from "ziggy";
import { Ziggy } from "./ziggy";
createInertiaApp({
resolve: async (name) => {
return (await import(`./Pages/${name}`)).default;
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue, Ziggy)
// .component("Link", Link)
// .component("Head", Head)
.mixin({ methods: { route } })
.mount(el);
},
progress: {
color: '#29d',
},
});
- เพิ่ม bootstrap ทั้ง css และ js
// /resources/css/app.css
@import 'bootstrap/dist/css/bootstrap.min.css';
// /resources/js/bootstrap.js
import "bootstrap";
- สร้าง layout ด้วย inertia /resources/js/Components/Layout.vue
<script setup>
import { Link } from '@inertiajs/vue3'
</script>
<template>
<main>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="background-color:#e3f2fd;">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<Link class="nav-link active" aria-current="page" href="/">Home</Link>
</li>
<li class="nav-item">
<Link class="nav-link active" aria-current="page" href="/about">About</Link>
</li>
<li class="nav-item">
<Link class="nav-link active" aria-current="page" href="/contact">Contact</Link>
</li>
</ul>
</div>
</div>
</nav>
<article>
<slot />
</article>
</main>
</template>
- สร้างหน้าเว็บ 3 หน้า ด้วยโค๊ด Vue /resources/js/Pages/Home.vue, /resources/js/Pages/About.vue, /resources/js/Pages/Contact.vue,
// /resources/js/Pages/Home.vue
<script>
import Layout from '../Components/Layout.vue'
export default {
// Using a render function...
layout: (h, page) => h(Layout, [page]),
// Using shorthand syntax...
layout: Layout,
}
</script>
<template>
<h1>Homepage</h1>
</template>
// /resources/js/Pages/Contact.vue
<script>
import Layout from '../Components/Layout.vue'
export default {
// Using a render function...
layout: (h, page) => h(Layout, [page]),
// Using shorthand syntax...
layout: Layout,
}
</script>
<template>
<h1>Contact</h1>
</template>
/ /resources/js/Pages/About.vue
<script>
import Layout from '../Components/Layout.vue'
export default {
// Using a render function...
layout: (h, page) => h(Layout, [page]),
// Using shorthand syntax...
layout: Layout,
}
</script>
<template>
<h1>About</h1>
</template>
- ทำการแก้ไข /routes/web.php route ของทั้ง 3 หน้าเว็บ
<?php
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/',function () {
return Inertia::render(
'Home',['title' => 'Homepage',]
);
}
)->name( 'homepage' );
Route::get('/about',function () {
return Inertia::render(
'About',['title' => 'About',]
);
}
)->name( 'about' );
Route::get('/contact',function () {
return Inertia::render(
'Contact',['title' => 'Contact',]
);
}
)->name( 'contact' );
รัน และทดสอบ
เราจะทำการรันคำสั่ง 2 คำสั่งคือ
- php artisan serve เพื่อ start server ด้วย port :8000
- npm run watch เพื่อสั่ง laravel mix ให้ compile js และ css แบบเรียวไทม์ทันที
// start server with 8000
php artisan serve
// start compile js, css with watch behavior
php run watch
ผลลัพธ์หลังจากรันคำสั่ง
สรุปท้ายบทความ
วิธีการขั้นตอนเหล่านี้ จะมีความยุ่งยากสักนิด แต่รับรองว่าเมื่อใช้งานไปแล้วสนุกแน่นอน สำหรับคนใดที่ถนัด react, svelt เป็นต้น inertiajs. ก็ยัง support ให้ใช้งานโดยไม่ยุ่งยากเลย ครั้งหน้าจะมาลองเขียนโค๊ดทำ APIs ให้ Vue เรียกใช้งานกัน คอยติดตามนะครับผม