如何用Vue判断Spatie Laravel-permissions生成的用户角色并渲染链接
解决方案
一、Spatie Roles数组的传递逻辑
Spatie的laravel-permissions包通过HasRoles trait给你的User模型绑定了roles关联关系。当Inertia在共享用户数据时(通常在HandleInertiaRequests中间件的share方法中),如果你的用户实例被序列化时包含了roles数据,前端就能拿到这个数组。
默认情况下,Inertia共享的用户数据不会自动包含角色,你需要在共享时显式添加:
// app/Http/Middleware/HandleInertiaRequests.php public function share(Request $request) { return array_merge(parent::share($request), [ 'auth' => [ 'user' => $request->user() ? $request->user()->only('id', 'name', 'email') + [ 'roles' => $request->user()->roles->pluck('name'), // 提取角色名称数组 ] : null, ], ]); }
如果你的User模型已经通过$appends或者重写toArray()方法自动包含了角色数组,直接共享用户实例即可,无需额外处理。
二、实现需求步骤
1. Laravel端确认角色数组传递
确保上述HandleInertiaRequests中的用户共享逻辑正确,这样前端$page.props.auth.user里就会有一个roles字符串数组(比如['Admin', 'Editor'])。
2. Vue端判断角色并渲染链接
你可以直接利用前端拿到的roles数组,通过includes()方法判断是否存在Admin角色,结合v-if渲染链接:
方式一:使用计算属性(推荐,代码更清晰)
<script setup> import { computed } from 'vue'; import { usePage } from '@inertiajs/vue3'; const page = usePage(); // 计算属性判断是否为Admin const isAdmin = computed(() => { // 用可选链避免用户未登录时的报错 return page.props.auth.user?.roles?.includes('Admin') || false; }); </script> <template> <div class="navbar"> <!-- 仅Admin可见的后台链接 --> <router-link v-if="isAdmin" :to="{ name: 'admin.dashboard' }"> 后台管理 </router-link> </div> </template>
方式二:直接在模板中判断
<template> <div class="navbar"> <router-link v-if="$page.props.auth.user?.roles?.includes('Admin')" :to="{ name: 'admin.dashboard' }" > 后台管理 </router-link> </div> </template>
注意事项
- 用
?.可选链操作符处理用户未登录的情况,避免Cannot read properties of undefined报错。 - 如果你的角色名称是大小写敏感的,要确保判断时的字符串和数据库中存储的完全一致(比如
'admin'和'Admin'是不同的)。
内容的提问来源于stack exchange,提问作者Cam
相关产品推荐
相关产品推荐

