共享数据

有时您需要在应用程序中的多个页面上访问特定数据。例如,您可能需要在网站标题中显示当前用户。在整个应用程序中手动传递每个响应中的此数据很麻烦。值得庆幸的是,有一个更好的选择:共享数据。

共享数据

Inertia 的服务器端适配器都提供了一种方法,可以使共享数据可用于每个请求。这通常在您的控制器之外完成。共享数据将自动与控制器中提供的页面道具合并。

在 Laravel 应用程序中,这通常由 HandleInertiaRequests 中间件处理,该中间件在安装 服务器端适配器 时会自动安装。

class HandleInertiaRequests extends Middleware
{
    public function share(Request $request)
    {
        return array_merge(parent::share($request), [
            // Synchronously...
            'appName' => config('app.name'),

            // Lazily...
            'auth.user' => fn () => $request->user()
                ? $request->user()->only('id', 'name', 'email')
                : null,
        ]);
    }
}
HandleInertiaRequests 中间件提供了一个 "share" 方法,您可以在其中定义自动与每个 Inertia 响应共享的数据。

或者,您可以使用 Inertia::share 方法手动共享数据。

use Inertia\Inertia;

// Synchronously...
Inertia::share('appName', config('app.name'));

// Lazily...
Inertia::share('user', fn (Request $request) => $request->user()
    ? $request->user()->only('id', 'name', 'email')
    : null
);
共享数据应该谨慎使用,因为所有共享数据都包含在每个响应中。
页面道具和共享数据合并在一起,因此请确保适当地命名空间您的共享数据,以避免冲突。

访问共享数据

在服务器端共享数据后,您就可以在任何页面或组件中访问它。以下是如何在布局组件中访问共享数据的示例。

<script setup>
import { computed } from 'vue'
import { usePage } from '@inertiajs/vue3'

const page = usePage()

const user = computed(() => page.props.auth.user)
</script>

<template>
  <main>
    <header>
      You are logged in as: {{ user.name }}
    </header>
    <content>
      <slot />
    </content>
  </main>
</template>

闪存消息

共享数据的另一个很好的用例是闪存消息。这些消息存储在会话中,仅供下一个请求使用。例如,在完成任务并重定向到另一个页面之前,通常会设置闪存消息。

以下是在 Inertia 应用程序中实现闪存消息的简单方法。首先,在每个请求上共享闪存消息。

class HandleInertiaRequests extends Middleware
{
    public function share(Request $request)
    {
        return array_merge(parent::share($request), [
            'flash' => [
                'message' => fn () => $request->session()->get('message')
            ],
        ]);
    }
}

接下来,在前端组件(例如网站布局)中显示闪存消息。

<template>
  <main>
    <header></header>
    <content>
      <div v-if="$page.props.flash.message" class="alert">
        {{ $page.props.flash.message }}
      </div>
      <slot />
    </content>
    <footer></footer>
  </main>
</template>