Vue3+Vuex+Laravel环境下无法存储用户会话至Vuex求助
Vue3 + Vuex + Laravel Fortify SPA登录:用户会话无法存入Vuex,但系统提示已登录
我是Vue和Vuex新手,正在用Vue3、Vuex、Fortify、Laravel构建SPA的登录功能。现在遇到的问题是:登录完成后用户信息没有存入Vuex,但再次尝试登录时系统提示已经处于登录状态。
相关代码
Login.vue
<template> <div class="grid login-container"> <div class="surface-card p-4 shadow-2 border-round w-full lg:w-6"> <div class="text-center mb-5"> <img src="images/blocks/logos/hyper.svg" alt="Image" height="50" class="mb-3"> <div class="text-900 text-3xl font-medium mb-3">Velkommen tilbage</div> <span class="text-600 font-medium line-height-3">Har du ingen konto?</span> <a class="font-medium no-underline ml-2 text-blue-500 cursor-pointer">Opret her idag!</a> </div> <div> <Form :validation-schema="schema" @submit="onSubmit"> <div class="mb-2"> <Field name="email" v-slot="{ field, errorMessage }"> <label for="email" class="block text-900 font-medium mb-2">E-mail</label> <InputText v-bind="field" :class="{ 'p-invalid': errorMessage }" type="text" class="w-full" aria-describedby="email-error" /> <small class="p-error" id="text-error">{{ errorMessage || ' ' }}</small> </Field> </div> <div class="mb-2"> <Field name="password" v-slot="{ field, errorMessage }"> <label for="password" class="block text-900 font-medium mb-2">Kodeord</label> <InputText v-bind="field" :class="{ 'p-invalid': errorMessage }" type="text" class="w-full" aria-describedby="password-error" /> <small class="p-error" id="text-error">{{ errorMessage || ' ' }}</small> </Field> </div> <div class="flex align-items-center justify-content-between mb-6"> <div class="flex align-items-center"> <Checkbox id="rememberme" :binary="true" v-model="rembemberMe" class="mr-2"></Checkbox> <label for="rememberme">Husk mig</label> </div> <a href="/reset" class="font-medium no-underline ml-2 text-blue-500 text-right cursor-pointer">Glemt koden?</a> </div> <Button type="submit" label="Log ind" icon="pi pi-user" class="w-full"></Button> </Form> </div> </div> </div> </template> <script setup> import Checkbox from 'primevue/checkbox'; import { mapActions } from 'vuex'; import { ref } from 'vue' import { Field, Form } from 'vee-validate'; import { da } from 'yup-locales'; import * as yup from 'yup'; const rembemberMe = ref(false) yup.setLocale(da); async function onSubmit(values, actions) { const mapActions = mapActions({ signIn:'auth/login' }); console.log(mapActions.user); await axios.get('/sanctum/csrf-cookie') await axios.post('/api/login', values).then(({ data }) => { this.signIn(); }).catch(({ response }) => { console.log(response.data); }); actions.resetForm(); } const schema = yup.object({ email: yup.string().email().required().label('E-mail'), password: yup.string().required().label('Kodeord'), }); </script> <style lang=""> </style>
resources/js/store/auth.js
import router from '../router' export default { namespaced: true, state:{ authenticated:false, user:{} }, getters:{ authenticated(state){ return state.authenticated }, user(state){ return state.user } }, mutations:{ SET_AUTHENTICATED (state, value) { state.authenticated = value }, SET_USER (state, value) { state.user = value } }, actions:{ login({commit}){ return axios.get('/api/user').then(({data})=>{ commit('SET_USER',data) commit('SET_AUTHENTICATED',true) router.push({name:'Home'}) }).catch(({response:{data}})=>{ commit('SET_USER',{}) commit('SET_AUTHENTICATED',false) }) }, logout({commit}){ commit('SET_USER',{}) commit('SET_AUTHENTICATED',false) } } }
resources/js/store/index.js
import { createStore } from 'vuex' import createPersistedState from 'vuex-persistedstate' import auth from './auth' const store = createStore({ plugins:[ createPersistedState() ], modules:{ auth } }) export default store
问题现象截图

问题原因及修复方案
1. <script setup>中mapActions使用错误
在<script setup>语法里,不能用this调用Vuex action,且你在onSubmit内部重复定义mapActions的写法完全错误。正确做法是通过useStore获取store实例,直接调用dispatch方法。
修改Login.vue的<script setup>部分:
import Checkbox from 'primevue/checkbox'; import { useStore } from 'vuex'; // 引入useStore import { ref } from 'vue' import { Field, Form } from 'vee-validate'; import { da } from 'yup-locales'; import * as yup from 'yup'; const rembemberMe = ref(false) const store = useStore(); // 获取store实例 yup.setLocale(da); async function onSubmit(values, actions) { await axios.get('/sanctum/csrf-cookie') await axios.post('/api/login', values).then(async () => { // 直接触发auth模块的login action await store.dispatch('auth/login'); }).catch(({ response }) => { console.log(response.data); }); actions.resetForm(); } const schema = yup.object({ email: yup.string().email().required().label('E-mail'), password: yup.string().required().label('Kodeord'), });
2. 未等待异步action完成
原代码调用action时没有加await,导致页面跳转或状态更新可能在用户信息获取完成前执行。修改后通过await确保Vuex状态更新完成后再进行后续操作。
3. 验证Laravel后端接口
确保/api/user路由已被auth:sanctum中间件保护,在routes/api.php中配置:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
4. 确认Vuex持久化生效
修复后打开浏览器开发者工具的Application标签,查看localStorage中的vuex键,确认用户信息已被持久化存储。
内容的提问来源于stack exchange,提问作者Pulsar
相关产品推荐
相关产品推荐

