You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue多组件中导入操作Cookie的工具函数并统一校验登录状态

Vue多组件统一登录状态校验方案

一、先修正原函数的核心问题

你的原函数存在两个关键问题:

  • const isLoggedOut是常量,无法被重新赋值
  • axios请求是异步操作,直接在then/catch里return无法拿到正确结果,函数实际返回undefined

方案1:传入组件实例给工具函数

把组件的this作为参数传给工具函数,就能直接调用$cookies:

import axios from "axios";
async function isLoggedOut(vm) { // vm即组件实例
  axios.defaults.withCredentials = true;
  const path = `/user_authentication/protected`;
  try {
    await axios.get(path, { withCredentials: true });
    return false; // 已登录
  } catch (error) {
    console.error(error);
    vm.$cookies.remove("csrf_access_token"); // 通过传入的vm操作cookie
    return true; // 未登录
  }
}

组件内使用:

async checkLogin() {
  const loggedOut = await isLoggedOut(this);
  if (loggedOut) {
    // 处理未登录逻辑,比如跳转登录页
  }
}

方案2:解耦依赖,传入cookie操作函数

如果不想让工具函数依赖Vue实例,可以把移除cookie的逻辑作为参数传入:

import axios from "axios";
async function isLoggedOut(removeCsrfToken) {
  axios.defaults.withCredentials = true;
  const path = `/user_authentication/protected`;
  try {
    await axios.get(path, { withCredentials: true });
    return false;
  } catch (error) {
    console.error(error);
    removeCsrfToken(); // 执行传入的移除cookie方法
    return true;
  }
}

组件内使用:

async checkLogin() {
  const loggedOut = await isLoggedOut(() => this.$cookies.remove("csrf_access_token"));
  if (loggedOut) {
    // 未登录处理
  }
}

二、推荐:全局统一处理(彻底避免重复代码)

上面的方式仍需每个组件手动调用,更推荐以下全局方案:

1. 路由守卫(Vue Router)

如果是页面级的登录校验,直接在路由全局守卫中统一处理:

// router/index.js
import axios from "axios";
import router from "./router";
import Cookies from 'js-cookie'; // 或项目中使用的cookie工具

router.beforeEach(async (to, from, next) => {
  // 给需要校验的路由添加requiresAuth元信息
  if (to.matched.some(record => record.meta.requiresAuth)) {
    axios.defaults.withCredentials = true;
    try {
      await axios.get(`/user_authentication/protected`, { withCredentials: true });
      next(); // 已登录,放行
    } catch (error) {
      console.error(error);
      Cookies.remove("csrf_access_token");
      next({ path: "/login" }); // 跳转到登录页
    }
  } else {
    next(); // 无需校验,直接放行
  }
});

路由配置示例:

{
  path: "/dashboard",
  component: Dashboard,
  meta: { requiresAuth: true } // 标记需要登录校验
}

2. Vue全局混入

如果是组件内部的细节校验(比如按钮权限),用全局混入统一注入校验方法:

// mixins/auth.js
import axios from "axios";

export default {
  methods: {
    async checkLoginStatus() {
      axios.defaults.withCredentials = true;
      try {
        await axios.get(`/user_authentication/protected`, { withCredentials: true });
        return false;
      } catch (error) {
        console.error(error);
        this.$cookies.remove("csrf_access_token");
        return true;
      }
    }
  }
}

在main.js全局注册:

import authMixin from './mixins/auth';
Vue.mixin(authMixin);

组件内直接调用:

async mounted() {
  const loggedOut = await this.checkLoginStatus();
  if (loggedOut) {
    // 处理未登录逻辑
  }
}

3. 状态管理(Pinia/Vuex)

用状态管理工具统一维护登录状态,只需初始化时校验一次,后续组件直接取状态:
以Pinia为例:

// stores/auth.js
import { defineStore } from 'pinia';
import axios from "axios";
import Cookies from 'js-cookie';

export const useAuthStore = defineStore('auth', {
  state: () => ({
    isLoggedIn: false,
    userInfo: null
  }),
  actions: {
    async checkAuth() {
      axios.defaults.withCredentials = true;
      try {
        const response = await axios.get(`/user_authentication/protected`, { withCredentials: true });
        this.isLoggedIn = true;
        this.userInfo = response.data.user;
        return true;
      } catch (error) {
        console.error(error);
        Cookies.remove("csrf_access_token");
        this.isLoggedIn = false;
        this.userInfo = null;
        return false;
      }
    }
  }
});

main.js初始化校验:

import { createPinia } from 'pinia';
import { useAuthStore } from './stores/auth';

const pinia = createPinia();
app.use(pinia);

const authStore = useAuthStore();
await authStore.checkAuth();

组件内直接使用状态:

import { useAuthStore } from '@/stores/auth';

export default {
  setup() {
    const authStore = useAuthStore();
    // 直接通过authStore.isLoggedIn判断登录状态
    return { authStore };
  }
}

内容的提问来源于stack exchange,提问作者adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:10:49