emargareten/inertia-modal

Inertia Modal 是一个 Laravel 扩展包,允许您为 Inertia 应用程序实现后端驱动的模态对话框。

v1.3.0 2024-04-30 14:52 UTC

This package is auto-updated.

Last update: 2024-09-13 20:10:07 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Inertia Modal 是一个 Laravel 扩展包,允许您为 Inertia 应用程序实现后端驱动的模态对话框。使用此扩展包,您可以在后端定义模态路由,并在访问对话框路由时动态渲染它们。

注意

此扩展包仅支持 Vue 3

安装

您可以通过 composer 安装此扩展包

composer require emargareten/inertia-modal

前端设置

警告

此扩展包在底层使用 axios。如果您的应用程序已经使用 axios 作为依赖项,请确保将其锁定到与 Inertia 使用相同的版本。

Modal 组件

Modal 是一个 无头 组件,这意味着您对其外观有完全控制权,无论是模态对话框还是滑动面板。您可以使用任何第三方解决方案来驱动您的模态,例如 Headless UI

Modal 组件放置在布局中的任何位置。

<script setup>
import { Modal } from '../../vendor/emargareten/inertia-modal'
</script>

<template>
  <div>
    <!-- layout -->
    <Modal />
  </div>
</template>

注意

确保整个应用程序中布局保持 持久。如果您有多个布局,请创建一个应调用模态的基础布局,使用嵌套布局。

插件

使用与渲染 Inertia 页面相同的组件解析器设置 modal 插件。

Vite

import { modal } from '../../vendor/emargareten/inertia-modal'

createInertiaApp({
  resolve: (name) => resolvePageComponent(name, import.meta.glob('./Pages/**/*.vue')),
  setup({ el, app, props, plugin }) {
    createApp({ render: () => h(app, props) })
      .use(modal, {
        resolve: (name) => resolvePageComponent(name, import.meta.glob('./Pages/**/*.vue')),
      })
      .use(plugin)
      .mount(el)
  }
})

Laravel Mix

import { modal } from '../../vendor/emargareten/inertia-modal'

createInertiaApp({
  resolve: (name) => require(`./Pages/${name}`),
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(modal, {
        resolve: (name) => import(`./Pages/${name}`),
      })
      .use(plugin)
      .mount(el)
  }
})

用法

模态有自己的路由,允许您通过直接 URL 访问它们。定义您的模态页面的路由。

// background context / base page
Route::get('users', [UserController::class, 'index'])->name('users.index');

// modal route
Route::get('users/{user}', [UserController::class, 'show'])->name('users.show');

从控制器中渲染模态。指定 base 路由以在直接访问模态时渲染背景。

use Emargareten\InertiaModal\Modal;
use Inertia\Inertia;

class UserController extends Controller
{
    // ...
    
    public function show(User $user): Modal
    {
        return Inertia::modal('Users/Show', ['user' => $user])->baseRoute('users.index');
    }
}

默认情况下,backdrop 组件将保留其当前 [过时] 数据(除了验证错误之外),在大多数情况下这很好,因为当关闭模态时(重定向到基本路由)它将刷新,如果您的应用程序需要 backdrop 的新鲜数据,请添加 refreshBackdrop 方法

    public function show(User $user): Modal
    {
        return Inertia::modal('Users/Show', ['user' => $user])
            ->baseRoute('users.index')
            ->refreshBackdrop();
    }

要强制将特定路由作为 backdrop,请添加 forceBase 方法

    public function show(User $user): Modal
    {
        return Inertia::modal('Users/Show', ['user' => $user])
            ->baseRoute('users.index')
            ->forceBase();
    }

这将强制重新渲染基本路由(甚至重定向到不同的基本路由)。

上述两种方法也可以接受一个布尔值来决定是否刷新等。

前端实现

在您的模态组件中使用 useModal() 可组合函数。

此示例是一个简单的 headlessui 模态,您可以根据需要添加更多过渡等,请参阅 https://headlessui.tailwind.org.cn/vue/dialog

<template>
  <TransitionRoot appear as="template" :show="show">
    <Dialog as="div" class="relative z-10" @close="close">
      <TransitionChild @after-leave="redirect" as="template">
        <div class="fixed inset-0 bg-black/75 transition-opacity" />
      </TransitionChild>

      <div class="fixed inset-0 overflow-y-auto">
        <div class="flex min-h-full items-center justify-center p-4 text-center">
          <TransitionChild as="template">
            <DialogPanel class="w-full max-w-lg transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
              <DialogTitle as="h3" class="text-lg font-medium leading-6 text-gray-900">
                <slot name="title" />
              </DialogTitle>
              <slot />
            </DialogPanel>
          </TransitionChild>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>

<script setup>
import { TransitionRoot, TransitionChild, Dialog, DialogPanel, DialogTitle } from '@headlessui/vue'
import { useModal } from '../../vendor/emargareten/inertia-modal'

const { show, close, redirect } = useModal()
</script>

redirect 方法将重定向到基本路由,您可以传递所有 inertia 访问选项作为参数。

redirect({ preserveScroll: true })

close 方法将关闭模态而不会重定向到基本路由。

注意

为了更简洁的设置,考虑配置别名而不是指定完整路径。

使用 vite

// vite.config.js
export default defineConfig({
  resolve: {
    alias: {
      'inertia-modal': path.resolve('vendor/emargareten/inertia-modal'),
    },
  },
});

使用 mix

// webpack.mix.js
mix.alias({
  'inertia-modal': path.resolve('vendor/emargareten/inertia-modal'),
});

现在您可以像这样导入模块

import { useModal } from 'inertia-modal'

测试

composer test

变更日志

请参阅 CHANGELOG 以获取有关最近更改的更多信息。

贡献

请参阅 CONTRIBUTING 以获取详细信息。

安全漏洞

请参阅 我们的安全策略 了解如何报告安全漏洞。

致谢

此包深受momentum-modal的启发

许可协议

MIT许可协议(MIT)。请参阅许可文件以获取更多信息。