- vừa được xem lúc

Inertiajs - Xây dựng Single Page App không cần API

0 0 242

Người đăng: Dương Mạnh Hoàng

Theo Viblo Asia

Tiêu đề là mình lấy từ trang chủ của https://inertiajs.com/ chứ không phải mình tự nghĩ ra đâu nhé :v. Lâu lâu rồi chưa động tới Laravel (dự án cuối cùng mình code là ở ver 5.8), thế nên một ngày đẹp trời lượn vào đọc docs ver 8.x tí và thấy cái gọi là Laravel Jetstream. Ngay ở phần Introduction mình đã đọc được 2 thứ nghe khá mới lạ đối với mình là LivewireInertia (có lẽ với nhiều bạn thì nó không mới lắm). Sau khi xem qua thì mình cảm thấy thích Inertia hơn nên quyết định tìm hiểu về nó. Inertia cho phép chúng ta dễ dàng tạo ra single page app một cách đơn giản hơn.

Cách hoạt động

Chúng ta vẫn sẽ xây dựng một app với model, controller, middleware,... như cách mà chúng ta thường làm khi xây dựng web với laravel. Điều khác ở đây là tầng view. Thay vì việc sử dụng server-side render, nay view sẽ là Javascript components. Nhưng mọi chuyện không chỉ dừng ở đây. Để mang lại trải nghiệm của SPA (single page app) thì khi click vào 1 link, nếu browser thực hiện load lại cả trang thì không ổn chút nào. Đó là lúc mà Inertia sẽ tham gia vào. Về cơ bản thì Inertia là một thư viện giúp thực hiện truy cập trang mà không phải reload lại toàn bộ trang. Điều này thực hiện nhờ sử dụng <inertia-link> component. Khi click vào một Inertia link, Inertia sẽ chặn lại và thay thế bằng XHR. Khi mà Inertia tạo ra một XHR request, server sẽ nhận biết được và thay vì trả về HTML, nó sẽ trả về JSON cùng với tên và data của component JS. Sau đó, Inertia sẽ đổi component trước thành component mới và update vào lịch sử state.

Cài đặt

Về phần tạo project Laravel thì mình sẽ không nói nữa nhé và mình sẽ sử dụng react để build frontend nhé. Đầu tiên thì bạn cần cài đặt laravel/ui:

composer require laravel/ui

Cài đặt react

php artisan ui react

Cài các dependencies của Inertia

Server side

composer require inertiajs/inertia-laravel

Sau khi cài đặt xong thì hãy tạo ra root template nhé. Mặc định Laravel adapter sẽ sử dụng file app.blade.php

<!DOCTYPE html>
<html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link href="{{ mix('/css/app.css') }}" rel="stylesheet" /> <script src="{{ mix('/js/app.js') }}" defer></script> </head> <body> @inertia </body>
</html>

Tạo middleware:

php artisan inertia:middleware

Ở trong file App\Http\Kernel, bạn hãy thêm đoạn này vào cuối group

'web' => [ // ... \App\Http\Middleware\HandleInertiaRequests::class,
],

Client side

Đầu tiên chạy lệnh:

npm install

Sau đó chúng ta sẽ cài thêm package liên quan

npm install @inertiajs/inertia @inertiajs/inertia-react

Ở file resources/js/app.js

import { App } from '@inertiajs/inertia-react'
import React from 'react'
import { render } from 'react-dom' const el = document.getElementById('app') render( <App initialPage={JSON.parse(el.dataset.page)} resolveComponent={name => require(`./Pages/${name}`).default} />, el
)

Giờ bạn chỉ cần khởi tạo server bằng lệnh

php artisan serve

và build giao diện bằng lệnh

npm run dev

để có thể tự động build lại mỗi lần có thay đổi thì bạn dùng lệnh

npm run watch-poll

Routing

Khi setup xong thì cta cùng tạo ra một cái view nhỏ để xem nhỉ. Muốn có view thì đầu tiện chúng ta phải có url để truy cập. Với nhưng view mà không cần data, chỉ đơn giản là render giao diện tĩnh ra thì các bạn có thể định nghĩa route trong web.php như sau:

Route::inertia('/', 'TestComponent');
import React from 'react'; const TestComponent = (props) => { return ( <div> <h1>This is test component</h1> </div> )
} export default TestComponent;

Giờ thì truy cập lại app bạn sẽ có kết quả như sau:

Giờ thì với view có data thì sao. Đầu tiên mình sẽ tạo ra TestController nhé:

<?php namespace App\Http\Controllers; use Inertia\Inertia; class TestController extends Controller
{ public function index() { $user = [ [ 'id' => 1, 'name' => 'Test 1', ], [ 'id' => 2, 'name' => 'Test 2', ] ]; return Inertia::render('TestComponent', [ 'users' => $user, ]); }
}

Ở đây thì mình fake tạm 1 ít dữ liệu. Sau đó sửa 1 ít ở TestComponent

import React from 'react'; const TestComponent = (props) => { const { users } = props; return ( <div> <h1>List test users</h1> { users.map(user => ( <p>{user.name}</p> )) } </div> )
} export default TestComponent;

Và kết quả:

Khá là đơn giản phải không nào ?. Thay vì dữ liệu ảo kia bạn có thể lấy dữ liệu từ DB thông qua Model hoặc viết Query builder. Thế là không phải mất công viết API và làm bao nhiêu thứ khác nữa

Pages

Về cơ bản thì pages là những javascript components thôi. Ở đây thì Pages sẽ nhận data từ controller trả về và đưa coi đó như props. Ví dụ như TestComponent ở trên sẽ được coi là 1 page

Tạo và sử dụng layout

Việc tạo layout và sử dụng đi sử dụng lại chắc cũng không xa lạ gì với anh em nữa rồi. Và InertiaJS cũng hỗ trợ chúng ta làm điều đó một cách khá dễ dàng. Ở đây thì mình sẽ đưa ra một ví dụ cơ bản thôi nhé, còn thực tế mình sử dụng như thế nào mình sẽ để trong bài xong, khi mà mình sẽ làm hẳn ra 1 demo khác

Giờ sẽ tạo 1 file Layout.js


import React from 'react';
import { InertiaLink } from '@inertiajs/inertia-react' const Layout = (props) => { const { children } = props; return ( <main> <header> <InertiaLink href="/">Home</InertiaLink> <InertiaLink href="/pages">Pages</InertiaLink> </header> <article>{children}</article> </main> )
} export default Layout;

ở file TestComponent thì các bạn thêm đoạn

TestComponent.layout = page => <Layout children={page} />

cụ thể:

import React from 'react';
import Layout from './Layout' const TestComponent = (props) => { const { users } = props; return ( <div> <h1>List test users</h1> { users.map(user => ( <p>{user.name}</p> )) } </div> )
} TestComponent.layout = page => <Layout children={page} /> export default TestComponent;

Và giờ view của chúng ta sẽ như này:

Bạn cũng có thể tạo ra các layout lồng nhau (hay trong docs gọi là nested layout)

import React from 'react'; const NestedLayout = (props) => { const { children } = props; return ( <div> This is nested layout <article>{children}</article> </div> )
} export default NestedLayout;
import React from 'react';
import Layout from './Layout';
import NestedLayout from './NestedLayout'; const TestComponent = (props) => { const { users } = props; return ( <div> <h1>List test users</h1> { users.map(user => ( <p>{user.name}</p> )) } </div> )
} TestComponent.layout = page => ( <Layout> <NestedLayout children={page} /> </Layout> ) export default TestComponent;

Kết quả:

Nhưng hay dùng nested layout một cách sáng suốt nhé. Nếu tất cả các pages của bạn đều cần tới component nested đó (ví dụ giờ có SidebarComponent chẳng hạn), thì hãy để nó là một component con của Layout chính, chứ đừng file nào cũng khai báo nested layout như này ?

Kết

Bài viết của mình đến đây thôi, cơ bản giới thiệu tới mọi người như vậy để nắm sơ sơ. Bài sau mình sẽ đi vào hẳn demo để có thể nói về những điều trong docs dễ hơn nhé ?. Dạo này cũng hơi bận nên khả năng bài sau sẽ ra muộn nên các bạn cũng tự thử làm demo trước xem sao nha ?

Tham khảo: https://inertiajs.com/

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 361

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 452

- vừa được xem lúc

Sử dụng Swagger để xây dựng API documentation

Giới thiệu về Swagger. RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource.

0 0 1k

- vừa được xem lúc

Ví dụ CRUD với Laravel và Vuejs.

1. Cài đặt Laravel. composer create-project --prefer-dist laravel/laravel vuelaravelcrud. .

0 0 163

- vừa được xem lúc

Một số tips khi dùng laravel (Part 1)

1. Show database query in raw SQL format. DB::enableQueryLog(); // Bật tính năng query logging. DB::table('users')->get(); // Chạy truy vấn bạn muốn ghi log.

0 0 84

- vừa được xem lúc

Laravel: Middleware SetCacheHeaders

Có rất nhiều middleware hữu ích đã được đăng ký bên trong Laravel, như cơ chế authentication, authorization, throttler và kể cả cơ chế route model binding. Ngoài ra còn có một middleware ít được nhắc đến là SetCacheHeaders, có alias là cache.

0 0 42