laravel 使用 inertiajs + vue3 开发项目
# 创建项目
composer create-project laravel/laravel example-app
# 安装 inertiajs
composer require inertiajs/inertia-laravel
php artisan inertia:middleware
# bootstrap/app.php
use App\Http\Middleware\HandleInertiaRequests;
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
HandleInertiaRequests::class,
]);
})
# resources/views/app.blade.php
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title inertia>{{ config('app.name', 'Laravel') }}</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
@vite('resources/js/app.js')
@inertiaHead
</head>
<body>
@inertia
</body>
</html>
安装前端组件包
@inertiajs/server
@inertiajs/vue3
nprogress
npm install vue@next
npm install @inertiajs/vue3
npm install nprogress
vite.config.js
import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import tailwindcss from '@tailwindcss/vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
ssr: 'resources/js/ssr.js',
}),
tailwindcss(),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
vueJsx(),
],
resolve: {
alias: {
'@': '/resources/js',
},
},
build: {
chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告
minify: 'esbuild', // Vite 2.6.x 以上需要配置 minify:"terser",terserOptions才能生效
},
});
创建 app.js
// resources/js/app.js
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import {createInertiaApp} from '@inertiajs/vue3';
import {resolvePageComponent} from 'laravel-vite-plugin/inertia-helpers';
import {createApp, h} from 'vue';
import 'nprogress/nprogress.css'
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
createInertiaApp({
title: (title) => title ? `${title}` : appName,
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({el, App, props, plugin}) {
createApp({render: () => h(App, props)})
.use(plugin)
.mount(el);
},
progress: {
color: '#1890ff',
delay: 200,
includeCSS: true,
showSpinner: true,
},
}).catch(reason => {
console.log(reason);
});
路由设置
Route::get('/', function () {
return Inertia::render('Index');
});
页面设置
// resources/js/Pages/Index.vue
<script setup lang="ts">
</script>
<template>
//// 直接使用vue3语法
<div>
<h1>Hello World</h1>
</div>
</template>
<style scoped lang="scss">
</style>
其中 Inertia::render('Index',['data' => []); render的第二个参数是传递给页面的参数 在对应的页面Index.vue中可以通过props接收
<script setup lang="ts">
defineProps({
data: {
type: Array,
default: () => []
},
})
也可以使用 usePage() 方法接收
const page = usePage()
console.log(page.props.data)
</script>
如果需要创建多端项目 可以使用laravel的路由分开 也可以使用前端vite的多个入口文件 来实现多端项目