如何使用 Inertia Js、Vue 和 Laravel 重新加载持久布局或观看道具

Posted

技术标签:

【中文标题】如何使用 Inertia Js、Vue 和 Laravel 重新加载持久布局或观看道具【英文标题】:How can I reload a persistent layout or watch props with InertiaJs, Vue & Laravel 【发布时间】:2022-01-13 17:55:24 【问题描述】:

我有一个带有 InertiaJs 和 Vue3 的 Laravel 项目。我有一个作为持久布局的导航,可以按预期工作。

我在用户和组织者之间有ManyToMany关系。 还有我的 KnowledgeBaseArticle 模型 belongsTo Organizer。 每个用户只能访问属于该用户所属的组织者的文章。 KnowledgeBaseArticle 模型有一个嵌套路由

Route::resource('organizers.knowledgebase_articles', KnowledgebaseArticleController::class)
        ->middleware(['permission:view_all_knowledgebase_articles|view_knowledgebase_articles']);

例如:test.com/organizers/1/konowledgebase_articles

并且用户可以更改当前组织者,这样他们就只能看到当前组织者的文章,这是一个发布路线,重定向回仪表板 .

// OrganizerController
public function change_organizer($organizer_id)
    
        $organizer = Organizer::findOrFail($organizer_id);
        abort_if(!$organizer->users()->where('users.id', auth()->user()->id)->exists(), 403);

        $user = auth()->user();
        $user->currentOrganizer()->associate($organizer_id);
        $user->save();

        session(['organizer_id' => $organizer->id, 'organizer_name' => $organizer->name]);

        return redirect()->route('organizer.dashboard');
    

// PersistentLayout.vue
function changeOrganizer(organizer_id) 
    Inertia.post(route('organizer.change',  id: organizer_id ));


当前组织者作为页面道具共享。

我的导航有一个持久布局

我的问题是,更改当前组织者后,导航链接与以前保持一致,并且导航链接中的组织者 ID 没有更新。

因此,即使我从 Organizer_id 1 更改为 2 并且 page prop 也更改为 2,导航链接仍然保持 test.com/organizers/1/knowledgebase_articles

我的问题是:我能否以某种方式触发页面的完全重新加载,包括持久布局,或者我将如何解决该问题?

这里是持久布局的一部分

<template>
                        <Menu as="div" class="ml-3 relative" v-if="props.auth.organizers">
                            <div>
                                <MenuButton class="max-w-xs bg-white flex items-center text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                                    <span> props.current_organizer.organizer_name </span>
                                </MenuButton>
                            </div>
                            <transition enter-active-class="transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
                                <MenuItems class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
                                    <MenuItem v-slot=" active " v-for="organizer in props.auth.organizers">
                                        <Link
                                            @click.prevent="changeOrganizer(organizer.id)"
                                            as="button">
                                             organizer.name 
                                        </Link>
                                    </MenuItem>
                                </MenuItems>
                            </transition>
                        </Menu>
</template>

<script setup>
import ref, watch from 'vue'

let props = defineProps(
    auth: Object,
    current_organizer: Object
);

let navigation = [
     name: 'Dashboard', href: route('dashboard'), icon: HomeIcon, type: 'parent' ,
     name: 'Organizers', href: route('organizers.index'), icon: BriefcaseIcon, type: 'parent' ,
     name: 'Knowledgebase', href: route('organizers.knowledgebase_articles.index', organizer: props.current_organizer.organizer_id), icon: InboxIcon, type: 'parent' ,
     name: 'Articles', href: route('organizers.knowledgebase_articles.index', organizer: props.current_organizer.organizer_id), icon: null, type: 'child' ,
     name: 'Categories', href: route('organizers.knowledgebase_categories.index', organizer: props.current_organizer.organizer_id), icon: null, type: 'child' ,

];

function changeOrganizer(organizer_id) 
    Inertia.post(route('organizer.change',  id: organizer_id ));

</script>

非常感谢!

【问题讨论】:

尝试使用当前路由向您的组件添加密钥。 感谢您的回答。你能解释一下你的意思吗?我不明白:) 【参考方案1】:

我就是这样做的。

<template>

 <your-menu-component :key="currentRoute"/>

</template>

<script>

export default 
computed: 
    currentRoute() 
        return location.pathname.substr(1)
    ,
  ,

当当前路由更改时,菜单组件的键发生更改。它将触发重新加载导航

【讨论】:

以上是关于如何使用 Inertia Js、Vue 和 Laravel 重新加载持久布局或观看道具的主要内容,如果未能解决你的问题,请参考以下文章

使用 Vue.Js / Inertia.js 和 Laravel 对结果进行分页

在 Inertia.js Vue 文件中访问 Laravel 的 .env 变量

使用 Inertia JS 从嵌套布局中控制 Vue 组件

如何使用 Inertia JS 在 Laravel 中默认编辑或删除身份验证的 URL?

如何在 Laravel 8 模块中使用 InertiaJS 加载 Vue 组件

为 Vue 使用 2 个不同的刀片根模板,以及 Laravel 8 和 Inertia?