【问题标题】:Insert localstorage with vuex使用 vuex 插入本地存储
【发布时间】:2021-12-03 00:16:44
【问题描述】:

我的脚本我正在使用 axios 和 vuex,但有必要在脚本中将 formData 更改为 Json,并且它从 POST/loginB2B 200 api 返回,但它不会插入到本地存储中所以它不会指向仪表板页面。

**Auth.js**

import axios from "axios";

const state = {
  user: null,
};

const getters = {
  isAuthenticated: (state) => !!state.user,
  StateUser: (state) => state.user,
};

  async LogIn({commit}, user) {
    await axios.post("loginB2B", user);
    await commit("setUser", user.get("email"));
  },

  async LogOut({ commit }) {
    let user = null;
    commit("logout", user);
  },
};

**Login.vue**

methods: {
    ...mapActions(["LogIn"]),
    async submit() {
      /*const User = new FormData();
      User.append("email", this.form.username)
      User.append("password", this.form.password)*/
      try {
          await this.LogIn({
            "email": this.form.username,
            "password": this.form.password
          })
          this.$router.push("/dashboard")
          this.showError = false
      } catch (error) {
        this.showError = true
      }
    },
  },

app.vue

  name: "App",
  created() {
    const currentPath = this.$router.history.current.path;
    if (window.localStorage.getItem("authenticated") === "false") {
      this.$router.push("/login");
    }
    if (currentPath === "/") {
      this.$router.push("/dashboard");
    }
  },
};

api /loginB2B 返回 200,但它没有创建存储以重定向到仪表板。

我使用这个例子,但是我需要传递 json 而不是 formData: https://www.smashingmagazine.com/2020/10/authentication-in-vue-js/

【问题讨论】:

  • 您说它不会在 localStorage 中存储任何内容,但我也没有看到您尝试在代码中存储任何内容。我有点不清楚为什么你认为它现在应该在那里存储一些东西。
  • 我插入了我的 app.vue 以显示代码从本地存储中获取值。

标签: vue.js axios vuex


【解决方案1】:

这里有几个问题:

  • 您调用了window.localStorage.getItem,但您从未在我们可以看到的任何地方调用window.localStorage.setItem,因此该项目可能始终为空。在这里使用 localStorage 似乎也不是一个很好的理由,因为您可以访问您的 vuex 存储。我在您提供的链接中注意到他们使用 vuex-persistedstate 包。默认情况下,这确实将内容存储在 localStorage 中的 vuex 键下,但您不应手动查询。
  • 您在App.vue 中使用created 生命周期挂钩,它通常是您启动应用程序时挂载的主要组件。这也意味着此生命周期挂钩中的代码在您登录之前执行,或者在应用程序中真正执行任何操作。而是使用来自 vue-router (https://router.vuejs.org/guide/advanced/navigation-guards.html) 的 Route Navigation Guards。
  • 不相关,但您没有检查 axios post 调用的响应,这意味着您依赖此调用始终返回不在 200 和 299 之间的状态代码,并且没有人会改变导致错误的状态代码范围以及导致响应的代码。扩大“成功”状态代码的范围并在此基础上执行自己的全局代码并不少见。这类端点返回 200 OK 状态代码并带有指示未发生登录的响应主体的情况也很常见,以使前端更容易向用户显示有用的内容。这可能会导致用户使用无效凭据登录。
  • 不相关,但 vuex 突变始终是同步的。你永远不应该await他们。

没有简单的方法可以解决您的问题,所以我建议从一开始就让它变得健壮。

为了正确解决您的问题,我建议在 router.js 中使用全局导航守卫,使用 meta 键标记哪些路由需要身份验证,哪些不需要身份验证,然后让全局导航守卫决定它是否允许您加载新路线。看起来您链接的文章走类似的路线。为了完整起见,我也会在这里发布给任何访问的人。

首先,修改 router/index.js 下的路由器文件以包含有关您包含的路由的元信息。通过从定义商店的文件中导入商店来加载商店。然后,我们将使用 Global Navigation Guard beforeEach 来检查用户是否可以继续使用该路线。

我们为每个路由定义了requiresAuth 元键,以检查我们是否需要重定向未登录的人。

路由器/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import store from '../store';

Vue.use(VueRouter);
const routes = [
  {
    path: '/',
    name: 'Dashboard',
    component: Dashboard,
    meta: {
      requiresAuth: true
    }
  },
  {
    path: '/login',
    name: 'Login',
    component: Login,
    meta: {
      requiresAuth: false
    }
  }
];

// Create a router with the routes we just defined
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

// This navigation guard is called everytime you go to a new route,
// including the first route you try to load
router.beforeEach((to, from, next) => {
  // to is the route object that we want to go to
  const requiresAuthentication = to.meta.requiresAuth;

  // Figure out if we are logged in
  const userIsLoggedIn = store.getters['isAuthenticated']; // (maybe auth/isAuthenticated if you are using modules)

  if (
    (!requiresAuthentication) ||
    (requiresAuthentication && userIsLoggedIn)
  ) {
    // We meet the requirements to go to our intended destination, so we call
    // the function next without any arguments to go where we intended to go
    next();

    // Then we return so we do not run any other code
    return;
  }

  // Oh dear, we did try to access a route while we did not have the required
  // permissions. Let's redirect the user to the login page by calling next
  // with an object like you would do with `this.$router.push(..)`.
  next({ name: 'Login' });
});

export default router;

现在您可以从 App.vue 中删除 created 挂钩。现在当你手动更改地址栏的url,或者使用this.$router.push(..)this.$router.replace(..)时,它会检查这个功能,如果你不被允许访问它会重定向到登录页面。

【讨论】:

  • 我正在使用导航防护,从我在代码中检查的内容来看,问题出在我正在使用导航防护,从我在代码中检查的内容来看,问题出在 api 调用和使用 user.get('email') 提交,因为它没有存储在存储中。直接在commit中设置值,去掉api中的query,就可以正常工作了。
  • 我该如何解决这个问题?
  • 我没听明白,但是,是的,因为它只是一个对象,所以你应该使用 user.email 而不是 user.get('email')。不使用try { .. } catch 方法的另一个原因是,您在向自己隐藏自己的错误。只需注释掉开头的 try { 和末尾的 catch(..) { ... },您应该会在控制台中获得一个不错的堆栈跟踪。
猜你喜欢
  • 2021-04-12
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多