关于 laravel-inertia-vue
laravel-inertia-vue 是面向 Laravel、Inertia.js 和 Vue 3 单体应用开发的技能,提供实践模式。其分优先级规则覆盖页面、表单、导航、共享数据、布局、上传及进阶界面模式。
主要功能
- 01六类共 24 条规则
- 02类型化 Inertia 页面组件
- 03表单与验证模式
- 04导航和共享数据指南
- 05持久化与嵌套布局
- 06上传及进阶页面模式
适用场景
- 01构建类型化 Inertia 页面组件
- 02处理表单提交与验证
- 03共享认证信息和闪存数据
- 04实现上传、轮询或无限滚动
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jasim-k/ laravel-agent-skills --skill laravel-inertia-vue安装后在 Claude Code 中输入/laravel-inertia-vue确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonREADME.mdrules/_sections.md_template.mdform-dirty-tracking.mdform-file-uploads.mdform-progress-indicator.mdform-reset-handling.mdform-transform-data.mdform-useform-basic.mdform-useform-hook.mdform-validation-errors.mdlayout-persistent.mdnav-external-links.mdnav-link-component.mdnav-preserve-state.mdnav-programmatic.mdnav-replace-history.mdpage-component-structure.mdpage-default-layout.mdpage-head-management.mdpage-partial-reloads.mdpage-props-typing.mdpage-scroll-preservation.mdshared-app-config.mdshared-auth-user.mdshared-flash-messages.mdshared-ziggy-routes.md详细介绍
Laravel + Inertia.js + Vue 3
使用 Laravel、Inertia.js 和 Vue 3 构建现代单体应用的全面模式。包含 30 多条规则,助力流畅的全栈开发。
适用场景
在以下情况下参考这些指南:
- 使用 Vue 3 创建 Inertia 页面组件
- 使用 useForm 组合式函数处理表单
- 管理共享数据和身份验证
- 实现持久化布局
- 在页面间导航
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 页面组件 | 严重 | page- |
| 2 | 表单与验证 | 严重 | form- |
| 3 | 导航与链接 | 高 | nav- |
| 4 | 共享数据 | 高 | shared- |
| 5 | 布局 | 中 | layout- |
| 6 | 文件上传 | 中 | upload- |
| 7 | 高级模式 | 低 | advanced- |
快速参考
1. 页面组件(严重)
page-props-typing- 为 Laravel 页面属性指定类型page-component-structure- 标准页面组件模式page-head-management- 使用 Head 管理标题和元标签page-default-layout- 为页面指定布局
2. 表单与验证(严重)
form-useform-basic- useForm 基本用法form-validation-errors- 显示 Laravel 验证错误form-processing-state- 处理表单提交状态form-reset-preserve- 重置或保留表单数据form-transform- 提交前转换数据
3. 导航与链接(高)
nav-link-component- 使用 Link 进行导航nav-preserve-state- 保留滚动位置和状态nav-partial-reloads- 仅重新加载发生变化的内容nav-replace-history- 替换或推入历史记录
4. 共享数据(高)
shared-auth-user- 访问已验证的用户shared-flash-messages- 处理闪现消息shared-global-props- 访问全局属性shared-typescript- 为共享数据指定类型
5. 布局(中)
layout-persistent- 持久化布局模式layout-nested- 嵌套布局layout-default- 默认布局指定layout-conditional- 条件布局
6. 文件上传(中)
upload-basic- 基本文件上传upload-progress- 跟踪上传进度upload-multiple- 多文件上传
7. 高级模式(低)
advanced-polling- 实时轮询advanced-prefetch- 预取页面advanced-modal-pages- 将模态框用作页面advanced-infinite-scroll- 无限滚动
核心模式
使用 TypeScript 的页面组件
<script setup lang="ts">
import { Head, Link } from '@inertiajs/vue3'
interface Post {
id: number
title: string
excerpt: string
created_at: string
author: {
id: number
name: string
}
}
interface Props {
posts: {
data: Post[]
links: { url: string | null; label: string; active: boolean }[]
}
filters: {
search?: string
}
}
const props = defineProps<Props>()
</script>
<template>
<Head title="Posts" />
<div class="container mx-auto py-8">
<h1 class="text-2xl font-bold mb-6">Posts</h1>
<div class="space-y-4">
<article
v-for="post in props.posts.data"
:key="post.id"
class="p-4 bg-white rounded-lg shadow"
>
<Link :href="route('posts.show', post.id)">
<h2 class="text-xl font-semibold hover:text-blue-600">
{{ post.title }}
</h2>
</Link>
<p class="text-gray-600 mt-2">{{ post.excerpt }}</p>
<p class="text-sm text-gray-400 mt-2">By {{ post.author.name }}</p>
</article>
</div>
</div>
</template>
使用 useForm 的表单
<script setup lang="ts">
import { Head, Link, useForm } from '@inertiajs/vue3'
interface Category {
id: number
name: string
}
interface Props {
categories: Category[]
}
const props = defineProps<Props>()
const form = useForm({
title: '',
body: '',
category_id: '',
})
function submit() {
form.post(route('posts.store'), {
onSuccess: () => form.reset(),
})
}
</script>
<template>
<Head title="Create Post" />
<form @submit.prevent="submit" class="max-w-2xl mx-auto py-8">
<div class="mb-4">
<label for="title" class="block font-medium mb-1">Title</label>
<input
id="title"
v-model="form.title"
type="text"
class="w-full border rounded px-3 py-2"
/>
<p v-if="form.errors.title" class="text-red-500 text-sm mt-1">
{{ form.errors.title }}
</p>
</div>
<div class="mb-4">
<label for="category" class="block font-medium mb-1">Category</label>
<select
id="category"
v-model="form.category_id"
class="w-full border rounded px-3 py-2"
>
<option value="">Select a category</option>
<option v-for="cat in props.categories" :key="cat.id" :value="cat.id">
{{ cat.name }}
</option>
</select>
<p v-if="form.errors.category_id" class="text-red-500 text-sm mt-1">
{{ form.errors.category_id }}
</p>
</div>
<div class="mb-4">
<label for="body" class="block font-medium mb-1">Content</label>
<textarea
id="body"
v-model="form.body"
rows="10"
class="w-full border rounded px-3 py-2"
/>
<p v-if="form.errors.body" class="text-red-500 text-sm mt-1">
{{ form.errors.body }}
</p>
</div>
<div class="flex gap-4">
<button
type="submit"
:disabled="form.processing"
class="px-4 py-2 bg-blue-600 text-white rounded disabled:opacity-50"
>
{{ form.processing ? 'Creating...' : 'Create Post' }}
</button>
<Link :href="route('posts.index')" class="px-4 py-2 border rounded">
Cancel
</Link>
</div>
</form>
</template>
持久化布局
<script setup lang="ts">
import { Link, usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
const page = usePage()
const auth = computed(() => page.props.auth as { user: { name: string } })
</script>
<template>
<div class="min-h-screen bg-gray-100">
<nav class="bg-white shadow">
<div class="container mx-auto px-4 py-3 flex justify-between">
<Link href="/" class="font-bold">My App</Link>
<span>Welcome, {{ auth.user.name }}</span>
</div>
</nav>
<main class="container mx-auto px-4 py-8">
<slot />
</main>
</div>
</template>
<script setup lang="ts">
import AppLayout from '@/Layouts/AppLayout.vue'
defineOptions({ layout: AppLayout })
</script>
<template>
<h1>Dashboard</h1>
</template>
Laravel 控制器
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StorePostRequest;
use App\Models\Post;
use App\Models\Category;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
use Inertia\Response;
class PostController extends Controller
{
public function index(): Response
{
return Inertia::render('Posts/Index', [
'posts' => Post::with('author:id,name')
->latest()
->paginate(10),
'filters' => request()->only('search'),
]);
}
public function create(): Response
{
return Inertia::render('Posts/Create', [
'categories' => Category::all(['id', 'name']),
]);
}
public function store(StorePostRequest $request): RedirectResponse
{
$post = Post::create([
...$request->validated(),
'user_id' => auth()->id(),
]);
return redirect()
->route('posts.show', $post)
->with('success', 'Post created successfully.');
}
public function show(Post $post): Response
{
return Inertia::render('Posts/Show', [
'post' => $post->load('author', 'category'),
]);
}
}
共享数据(HandleInertiaRequests)
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
class HandleInertiaRequests extends Middleware
{
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user() ? [
'id' => $request->user()->id,
'name' => $request->user()->name,
'email' => $request->user()->email,
] : null,
],
'flash' => [
'success' => $request->session()->get('success'),
'error' => $request->session()->get('error'),
],
]);
}
}
闪现消息组件
<script setup lang="ts">
import { usePage } from '@inertiajs/vue3'
import { computed, ref, watch } from 'vue'
const page = usePage()
const flash = computed(() => page.props.flash as { success?: string; error?: string })
const visible = ref(false)
let timer: ReturnType<typeof setTimeout> | null = null
watch(flash, (newFlash) => {
if (newFlash.success || newFlash.error) {
visible.value = true
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
visible.value = false
}, 3000)
}
}, { deep: true })
</script>
<template>
<div v-if="visible" class="fixed top-4 right-4 z-50">
<div
v-if="flash.success"
class="bg-green-500 text-white px-4 py-2 rounded shadow"
>
{{ flash.success }}
</div>
<div
v-if="flash.error"
class="bg-red-500 text-white px-4 py-2 rounded shadow"
>
{{ flash.error }}
</div>
</div>
</template>
使用方法
阅读各条规则文件,了解详细说明和代码示例:
rules/form-useform-basic.md
rules/page-props-typing.md
rules/layout-persistent.md
项目结构
laravel-inertia-vue/
├── SKILL.md # This file - overview and examples
├── README.md # Quick reference guide
├── AGENTS.md # Integration guide for AI agents
├── metadata.json # Skill metadata and references
└── rules/
├── _sections.md # Rule categories and priorities
├── _template.md # Template for new rules
├── page-*.md # Page component patterns (6 rules)
├── form-*.md # Form handling patterns (8 rules)
├── nav-*.md # Navigation patterns (5 rules)
├── shared-*.md # Shared data patterns (4 rules)
└── layout-*.md # Layout patterns (1 rule)
参考资料
- Inertia.js 文档 - Inertia.js 官方文档
- Laravel 文档 - Laravel 框架文档
- Vue 3 文档 - Vue 3 官方文档
- Ziggy - 用于 JavaScript 的 Laravel 路由助手
许可证
MIT 许可证。本技能按原样提供,用于教育和开发目的。
元数据
- 版本:1.0.0
- 最近更新:2026-03-17
- 维护者:Jasim K
- 规则数量:6 个类别,共 24 条规则
- 技术栈:Laravel 12+、Inertia.js 2.0+、Vue 3.3+、TypeScript 5+
评论
支持 Markdown