支持Laravel.io的持续开发 →

使用TypeScript和Vue 3的组合API增强Laravel和Inertia.js,构建强大的SPA

6 Nov, 2023 5 min read

简介

Laravel结合Inertia.js,为创建现代单页应用提供了一对强大的组合,这些应用在复杂性上与使用Vue.js或React的全前端框架相媲美。本文将引导您通过将Laravel与Inertia.js和Vue 3结合使用的过程,并进一步介绍TypeScript在Vue的Composition API中的使用。

先决条件

  • 在您的本地机器上已安装Composer
  • 已安装Node.js和npm/yarn
  • 具备Laravel、Vue.js和TypeScript的基本知识

设置Laravel与Inertia.js

创建一个新的Laravel项目并导航到项目目录

composer create-project laravel/laravel inertia-example
cd inertia-example

使用Composer安装Inertia.js

composer require inertiajs/inertia-laravel

并发布Inertia.js配置

php artisan inertia:middleware

确保在app/Http/Kernel.php中的web中间件组末尾注册Inertia中间件。

集成Vue 3和TypeScript

在Laravel设置完成后,让我们将关注点转移到前端。安装Vue 3和Inertia.js的Vue适配器

npm install vue @inertiajs/vue3 @types/ziggy-js lodash --save-dev

添加TypeScript及其Vue插件

npm install typescript @vitejs/plugin-vue vue-tsc --save-dev

为TypeScript设置tsconfig.json

{  
    "compilerOptions":{  
        "allowJs":true,  
        "module":"ESNext",  
        "moduleResolution":"Node",  
        "target":"esnext",  
        "jsx":"preserve",  
        "strict":true,  
        "esModuleInterop":true,  
        "skipLibCheck":true,  
        "forceConsistentCasingInFileNames":true,  
        "noEmit":true,  
        "isolatedModules":true,  
        "types": ["vite/client"]  
    },    
    "include":[  
        "resources/js/**/*.ts",  
        "resources/js/**/*.d.ts",  
        "resources/js/**/*.vue"  
    ]  
}

现在,让我们创建所需的TypeScript类型

前往 resources/js 目录,创建一个名为 types 的目录,在该目录中创建一个 TS 文件名为 global.d.ts,并将以下内容复制到文件中

import { PageProps as InertiaPageProps } from '@inertiajs/core';
import { AxiosInstance } from 'axios';
import ziggyRoute, { Config as ZiggyConfig } from 'ziggy-js';
import { PageProps as AppPageProps } from './';

declare global {
    interface Window {
        axios: AxiosInstance;
    }

    var route: typeof ziggyRoute;
    var Ziggy: ZiggyConfig;
}

declare module 'vue' {
    interface ComponentCustomProperties {
        route: typeof ziggyRoute;
    }
}

declare module '@inertiajs/core' {
    interface PageProps extends InertiaPageProps, AppPageProps {}
}

为 Vue 中的路由处理安装 Ziggy

Ziggy 是由 Tighten 开发的一个包,用于在 Laravel 中共享来自 routes/web.php 的路由到客户端。

composer require tightenco/ziggy

更新前端构建工具

通过调整你的 vite.config.js 来配置 Vite 以使用 TypeScript

import { defineConfig } from 'vite';  
import laravel from 'laravel-vite-plugin';  
import vue from '@vitejs/plugin-vue';  
import path from 'path';  
  
  
export default defineConfig({  
    "plugins":[  
        laravel({  
            "input": [  
                "resources/css/app.css",  
                "resources/js/app.ts"  
            ],  
            "refresh": true  
        }),  
        vue({  
            template: {  
                transformAssetUrls: {  
                    base: null,  
                    includeAbsolute: false,  
                },            
			},       
		 })    
	 ],
 });

修改 package.json 以包括 TypeScript 编译和 Vite 构建过程的脚本

"scripts": {  
    "dev": "vite",  
    "build": "vue-tsc --noEmit && vite build",  
    "ts-check": "vue-tsc --noEmit"  
},

resources/js/app.ts 中更新你的入口点为 TypeScript,并确保将 resources/js/app.js 的扩展名更改为 app.ts,以及将 bootstrap.js 更改为 bootstrap.ts

import './bootstrap';  
import '../css/app.css';  
  
import { createApp, h, DefineComponent } from 'vue';  
import { createInertiaApp } from '@inertiajs/vue3';  
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';  
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.es';  
  
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';  
  
createInertiaApp({  
    title: (title) => `${title} - ${appName}`,  
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob<DefineComponent>('./Pages/**/*.vue')),  
    setup({ el, App, props, plugin }) {  
        createApp({ render: () => h(App, props) })  
            .use(plugin)  
            .use(ZiggyVue, Ziggy)  
            .mount(el);  
    },    progress: {  
        color: '#4B5563',  
    },});  

定义路由和视图

resources/views/app.blade.php 中创建布局文件

<!DOCTYPE html>  
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="h-full bg-gray-100">  
<head>  
    <meta charset="utf-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1">  
  
    <title inertia>{{ config('app.name', 'Laravel') }}</title>  
  
    <!-- Fonts -->  
    <link rel="preconnect" href="https://fonts.bunny.net">  
    <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />  
  
    <!-- Scripts -->  
    @routes  
    @vite(['resources/js/app.ts', "resources/js/Pages/{$page['component']}.vue"])  
    @inertiaHead  
</head>  
<body class="font-sans antialiased h-full">  
@inertia  
</body>  
</html>

routes/web.php 中定义你的 Inertia 路由

Route::get('/', function () {  
    return Inertia\Inertia::render('Welcome');  
});  
  
Route::get('/about', function () {  
    return Inertia\Inertia::render('About');  
});

确保你在 resources/js/Pages 目录中创建了相应的 Vue 组件。

使用 TypeScript 与 Vue 的 Composition API

为了在 Vue 组件中利用 TypeScript,使用 <script setup lang="ts"> 语法,这简化了 Composition API 的使用。

示例 resources/js/Pages/Welcome.vue

<script setup lang="ts">  
import { ref } from 'vue';  
import { Link } from '@inertiajs/vue3';  
  
const greeting = ref('Welcome to Your Vue.js + TypeScript App');  
  
</script>

<template>  
    <h1>{{ greeting }}</h1>  
    <Link href="/about">Go to About page</Link>  
</template>

以及另一个 About.vue

<template>  
    <h1>{{ greeting }}</h1>  
    <Link href="/">Go to Welcome page</Link>  
</template>  
  
<script setup lang="ts">  
import { ref } from 'vue';  
import { Link } from '@inertiajs/vue3';  
  
const greeting = ref('Welcome to About page');  
  
</script>

结论

将 TypeScript 与 Laravel、Inertia.js 以及 Vue 3 的 Composition API 集成可能在最初时显得有些挑战,但它对开发效率和性能的提升是非常值得的。通过这种设置,你可以获得 TypeScript 的类型检查能力、Vue 3 的反应性和可组合性,以及 Inertia.js 提供的无缝交互性,所有这些都在一个强大的 Laravel 应用程序中。

为了进一步探索,可以考虑深入了解 TypeScript 的高级功能、Vuex 或 Pinia 中的状态管理,以及 Inertia 路由链接的自动类型生成。

最后更新于 8 个月前。

driesvints 赞同了这篇文章

1
喜欢这篇文章吗? 让作者知道,并给他们鼓掌!
bcryp7 (Alberto Rosas) 嗨,我是 Alberto。作为一名资深软件工程师和顾问。

你可能还会喜欢的其他文章

2024年3月11日

使用Larastan将您的Laravel应用程序从0提升到9

在Laravel应用程序执行之前找到错误是可能的,多亏了Larastan,它是一个...

阅读文章
2024年7月19日

无需特性标准化API响应

我注意到大多数用于API响应的库都是使用特性实现的,并且...

阅读文章
2024年7月17日

在Laravel项目中通过Discord通知收集反馈

如何在Laravel项目中创建反馈模块,并在收到消息时收到Discord通知...

阅读文章

我们想感谢这些 极棒的公司 对我们的支持

您的标志在哪里?

Laravel.io

Laravel的解决问题、知识共享和社区建设的门户。

© 2024 Laravel.io - 版权所有。