Vue.js란
Vue.js(이하 Vue)는 사용자 인터페이스를 구축하기 위한 프로그레시브 JavaScript 프레임워크입니다. “프로그레시브”란 작은 부분부터 시작하여 필요에 따라 기능을 추가해 갈 수 있다는 의미로, 기존 HTML 페이지로의 부분적인 편입도, 대규모 SPA의 구축에도 대응할 수 있습니다. Vue의 핵심은 리액티비티입니다. 데이터가 바뀌면 DOM이 자동으로 갱신되므로, 개발자는 “언제, 어느 요소를 갱신할지”를 수동으로 관리할 필요가 없습니다.이 페이지에서 설명하는 것은 Vue 3와 Inertia v3의 조합입니다. Laravel 13의 스타터 킷은 이 구성을 기본으로 사용합니다.
Options API와 Composition API
Vue 3는 컴포넌트를 작성하는 스타일로서 Options API와 Composition API의 두 가지를 제공하고 있습니다. Options API는 Vue 2부터 이어지는 기존 스타일입니다.data · methods · computed · mounted 등의 옵션 오브젝트로 컴포넌트를 정의합니다.
<script setup> 구문과 조합함으로써 보다 간결하게 쓸 수 있습니다. 로직의 재이용성도 높고, TypeScript와의 궁합도 뛰어납니다.
Laravel에서의 포지션
역사
Vue와 Laravel의 관계는 오래되었으며, **Laravel 5.3(2016년)**에 Vue가 기본 프론트엔드 프레임워크로 채용된 것에서 시작합니다. 당시의package.json에는 Vue가 포함되어 있었고, resources/js/components/ExampleComponent.vue라는 샘플 컴포넌트도 동봉되어 있었습니다.
**Laravel 6(2019년)**에서 인증 스캐폴드가 laravel/ui 패키지로 분리되어, Vue의 스캐폴드도 동 패키지로 이관되었습니다. 현재는 laravel new의 스타터 킷 경유로 Inertia + Vue 구성을 선택하는 것이 주류 스타일입니다.
Laravel 사용자에게 있어 Vue는 가장 익숙한 JS 프레임워크이며, 한국어 학습 리소스도 풍부합니다.
현재의 주류 스타일: Inertia × Vue
현재 Laravel에서 Vue 사용법의 중심은 Inertia × Vue입니다. Inertia는 API를 설계하지 않고 Laravel의 컨트롤러에서 직접 Vue 컴포넌트에 데이터를 전달할 수 있는 “모던 모놀리스” 아키텍처를 실현합니다.셋업
스타터 킷 경유 (권장)
신규 프로젝트에서 시작하는 경우에는 스타터 킷을 사용하는 것이 가장 손쉽습니다.inertiajs/inertia-laravel(서버사이드 어댑터)@inertiajs/vue3(클라이언트 어댑터)vue(Vue 3 본체)@vitejs/plugin-vue(Vite 플러그인)HandleInertiaRequests미들웨어- 로그인 · 회원가입 등의 인증 화면 (Inertia + Vue로 구현 완료)
수동 설치
기존 프로젝트에 추가하는 경우에는 서버사이드와 클라이언트사이드를 별도로 설치합니다.vite.config.js에 Vue 플러그인을 추가합니다.
resources/js/app.js에서 Inertia 앱을 기동합니다.
수동 설치의 세부 내용(루트 템플릿의 설정이나 미들웨어의 등록 등)은 Inertia 공식 문서를 참고하세요.
디렉터리 구조
스타터 킷에서는 Vue의 페이지 컴포넌트를resources/js/pages/ 디렉터리에 배치합니다.
Inertia::render('Posts/Index', [...])이라고 쓰면 resources/js/pages/Posts/Index.vue가 대응하는 컴포넌트가 됩니다.
Vue 템플릿 구문
스타터 킷의 코드를 읽고 쓰기 위해 필요한 기본적인 템플릿 디렉티브를 소개합니다.{{ }} — 변수 전개
이중 중괄호를 사용하여, JavaScript의 값이나 식을 템플릿에 삽입합니다.
v-if — 조건 분기
{#if}나 React의 삼항 연산자에 해당합니다.
v-for — 리스트 렌더링
:key는 반드시 지정합니다. React의 Array.map()에 해당합니다.
v-model — 양방향 바인딩
v-model을 사용하면 폼 요소의 값과 리액티브 변수를 양방향으로 동기화할 수 있습니다.
: (v-bind)와 @ (v-on)
:attr="value"— HTML 속성에 동적인 값을 바인드 (v-bind:attr의 생략형)@event="handler"— 이벤트 리스너를 등록 (v-on:event의 생략형)
페이지 컴포넌트의 기본
Inertia의 페이지 컴포넌트는 일반적인 Vue 컴포넌트입니다. Laravel의 컨트롤러에서 전달된 데이터를 props로 받을 수 있습니다.컨트롤러
Vue 페이지 컴포넌트
defineProps()로 props를 선언하는 것만으로, 컨트롤러에서 전달된 데이터를 템플릿에서 사용할 수 있습니다. REST API를 정의할 필요는 없습니다.
Link 컴포넌트
@inertiajs/vue3가 제공하는 <Link> 컴포넌트를 사용하면, 페이지 전환이 XHR로 이루어져, 브라우저의 풀 리로드를 회피할 수 있습니다.
<a> 태그와 같은 방식으로 작성할 수 있지만, 뒤에서 Inertia가 페이지 컴포넌트만을 교체하므로 SPA 같은 조작감이 됩니다.
Form 컴포넌트
@inertiajs/vue3가 제공하는 <Form> 컴포넌트는, 스타터 킷의 인증 화면에서 사용되고 있는 폼 송신의 권장 스타일입니다. action과 method를 props로 지정하고, v-slot으로 errors와 processing에 접근합니다.
기본 사용법
v-slot="{ errors, processing }"은 Vue의 스코프 부여 슬롯 구문으로, Form 컴포넌트가 이 값들을 자동으로 산출하여 전달해 줍니다. 폼 필드에는 v-model이 아니라 HTML 네이티브의 name 속성을 사용하고, 브라우저의 표준 폼 데이터 수집이 기능합니다.
스타터 킷의 패턴
스타터 킷은 Wayfinder를 사용하여 라우트를 오브젝트로 관리하고 있습니다.store.form()은 라우트 오브젝트의 action과 method를 포함하는 오브젝트를 반환하고, v-bind로 <Form>에 spread합니다.
reset-on-success에 지정한 필드는 송신 성공 시에 자동으로 리셋됩니다. 패스워드 필드 등 송신 후에 비우고 싶은 필드에 지정합니다.
Wayfinder를 사용하지 않는 경우는
action="/login"처럼 직접 URL을 전달하면 같은 방식으로 동작합니다.useForm 헬퍼
폼 처리에는 @inertiajs/vue3의 useForm 헬퍼를 사용합니다. 폼의 상태 관리 · 송신 · 유효성 검증 오류 표시를 심플하게 구현할 수 있습니다.
컨트롤러 측
Vue 폼 컴포넌트
useForm이 반환하는 오브젝트의 주요 프로퍼티를 정리합니다.
유효성 검증 오류가 반환되었을 때,
useForm은 입력 내용을 유지한 채 오류를 표시합니다. v-model과의 조합으로 심리스한 폼 경험을 실현할 수 있습니다.
공유 데이터 (Shared Data)
모든 페이지에서 공통으로 필요한 데이터(로그인 중인 사용자 정보 · 플래시 메시지 등)는HandleInertiaRequests 미들웨어의 share() 메서드로 정의합니다.
usePage()를 사용합니다.
공유 데이터는 모든 요청에 포함되므로, 필요 최소한의 데이터로 좁힐 것을 권장합니다.
fn()을 사용한 지연 평가로 하면, 실제로 접근되었을 때만 평가됩니다.Vue 3의 리액티비티 기초
Inertia × Vue로 개발할 때 알아 두어야 할 Vue 3의 리액티비티 API를 소개합니다.ref — 프리미티브한 리액티브 값
computed — 산출 프로퍼티
onMounted — 마운트 후의 처리
정리
Vue.js는 Laravel과의 친화성이 높으며, 특히 Inertia를 경유한 “모던 모놀리스” 구성에서 힘을 발휘합니다.
Inertia × Vue를 사용하면, Laravel 백엔드의 심플함과 Vue의 리액티브한 UI 양쪽을 향유할 수 있습니다. 스타터 킷으로 프로젝트를 생성하면 인증 화면도 포함해서 바로 개발을 시작할 수 있습니다.
Inertia.js 공식 문서
Inertia v3의 전체 기능에 대해서는 공식 문서를 참고하세요.