Vue:标题没有立即刷新。但是localStorage改变了

par*_*cer 2 javascript vue.js vuejs2

当我使用表单登录时,会发生这种情况:

  1. localStorage中的loggedIn值更改为“true”
  2. 路由器推送到/home
  3. 标题没有改变,仍然显示登录/注册按钮

我需要它是

  1. localStorage中的loggedIn值更改为“true”
  2. 路由器推送到/home
  3. 标题更改和图片

标题.vue

      <div class="flex flex-wrap items-center justify-end ">
        <HeaderItem v-if="!isLoggedIn"
            class="pl-10" text = "Login" link="/login"/>
        <HeaderItem v-if="!isLoggedIn" class="pl-10"
                    text = "Signup" link="/signup"/>

        <div v-if="isLoggedIn">
          <UserHeader/>
        </div>
      </div>
Run Code Online (Sandbox Code Playgroud)

export default {
  name: 'App',
  components: {HeaderItem, UserHeader},
  data() {
    return {
      homeLink: "/home"
    }
  },
  created: {
    isLoggedIn() {
      console.log(JSON.parse(localStorage.getItem("loggedIn")) === "true");

      if (localStorage.getItem("loggedIn") === "true")  {
        console.log("STORAGE LOGGED IN TRUE");
      }
      else  {
        console.log("STORAGE LOGGED IN FALSE");
      }

      return localStorage.getItem("loggedIn") === "true";
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在我按 Ctrl+Shift+R 后,它只会打印正确的消息并更改标题。但 localStorageloggedIn立即具有正确的值。我如何解决它?

编辑

我也尝试过这个:

  <div class="flex flex-wrap items-center justify-end ">
        <HeaderItem v-if="!loggedIn"
            class="pl-10" text = "Login" link="/login"/>
        <HeaderItem v-if="!loggedIn" class="pl-10"
                    text = "Signup" link="/signup"/>

        <div v-if="loggedIn">
          <UserHeader/>
        </div>
      </div>
Run Code Online (Sandbox Code Playgroud)

export default {
  name: 'App',
  components: {HeaderItem, UserHeader},
  data() {
    return {
      homeLink: "/home",
     // loggedIn: false
    }
  },
  computed: {
    loggedIn() {
      return localStorage.getItem("loggedIn") === "true";
    },
...
Run Code Online (Sandbox Code Playgroud)

它具有相同的结果:标题仅在页面刷新(Ctrl+Shift+R)后更改。

编辑

无法设置localStorage.loggedIn里面Header!它是在LoginForm.vue中设置的,完全不同的组件

Jor*_*dan 6

本地存储不是反应性的,因此 VueJS 无法检测到它的更改。因此,您的计算属性无法跟踪对其的更改

它在重新加载时起作用的原因是计算方法将始终至少运行一次以生成初始值。

您需要将本地存储的更新与布尔值等反应变量联系起来。

每次访问本地存储对象时,检查存储值并在 VueJS 中设置一个布尔值 - 类似isLoggedIn并使用它而不是计算方法。

您可以使用 Vuex 和提交,也可以简单地设置标头组件的状态。

例如,当创建组件时,您可以设置isLoggedIn为 true 或 false,具体取决于本地存储密钥是否存在。

同样,您还可以isLoggedIn在用户登录时设置为 true(与设置本地存储密钥的方法相同),在用户注销时设置为 false。

考虑以下示例:

标题.vue

  <div class="flex flex-wrap items-center justify-end ">
    <HeaderItem v-if="!isLoggedIn"
        class="pl-10" text = "Login" link="/login"/>
    <HeaderItem v-if="!isLoggedIn" class="pl-10"
                text = "Signup" link="/signup"/>

    <div v-if="isLoggedIn">
      <UserHeader/>
    </div>
  </div>

export default {
  name: 'App',
  components: {HeaderItem, UserHeader},
  data() {
    return {
      homeLink: "/home",
      isLoggedIn: false,
    }
  },
  computed: {
      isLoggedIn() {
          return this.$store.state.isLoggedIn;
      }
  },
}
Run Code Online (Sandbox Code Playgroud)

然后在任何其他组件中

  created() {
      if (localStorage.getItem("loggedIn") === "true")  {
          this.$store.commit('SET_LOGGED_IN', true);
      }
  },
  methods: {
       login() {
           localStorage.setItem('loggedIn', 'true');
           this.$store.commit('SET_LOGGED_IN', true); 
       }
  }
Run Code Online (Sandbox Code Playgroud)

对于上面的示例,您有一个 Vuex 存储,其布尔状态称为isLoggedIn。然后,您提交一个名为 的突变SET_LOGGED_IN,将 的状态设置isLoggedIn为 true 或 false。

在任何组件中使用计算属性,您可以轻松访问其值isLoggedIn并响应其中的更改。

每次更新或从本地存储读取时,还必须更新 VueJS 中的变量。该变量就是反应性的。