Skip to main content

判断用户登录状态

在前面的课程中,我们实现了用户的登录功能,并成功记录了用户的登录状态。接下来,我们需要在页面中根据用户的登录状态进行相应的操作。

使用Vuex State保持用户状态

在Vue项目中,我们通常使用Vuex的State来保持各种状态信息,比如用户的登录状态。在我们的Vue项目中,会有一个Store,通常在index.js中,我们可以在这里的State中添加一个isLogin属性来表示用户的登录状态。初始值默认为false

frontend/src/store/index.js
import { createStore } from 'vuex'

export default createStore({
state: {
isLogin: false
},
getters: {
},
mutations: {
initializeStore(state) {
if (localStorage.getItem('token')) {
state.isLogin = true
}
else {
state.isLogin = false
}
},
setLoginStatus(state, status) {
state.isLogin = status
}
},
actions: {
},
modules: {
}
})
代码解析

这是一个使用 Vuex 状态管理库的 Vue.js 项目的 store(仓库)配置文件。让我们逐步解释这段代码:

  1. 从 Vuex 库中导入 createStore 函数,用于创建 Vuex store 实例。

  2. 创建 Vuex store 实例:

    使用 createStore 函数创建 Vuex store 实例,该实例包含以下部分:

    • state: 包含应用级别状态的对象。在这里,有一个名为 isLogin 的状态,用于表示用户是否已登录,默认为 false
    • getters: 用于获取 state 中的数据的计算属性。在这里没有定义额外的 getters
    • mutations: 包含同步修改 state 的方法。在这里,有两个 mutations:
      • initializeStore: 用于初始化 state 中的 isLogin 状态,根据本地存储中的 token 存在与否来设置登录状态。
      • setLoginStatus: 用于设置 isLogin 的状态,接收一个布尔值 status 作为参数,用于表示用户的登录状态。
    • actions: 包含异步操作和业务逻辑的方法。在这里没有定义额外的 actions
    • modules: 用于将 store 拆分为模块的对象。在这里没有定义额外的模块。
  3. initializeStore Mutation:

    initializeStore(state) {
    if (localStorage.getItem('token')) {
    state.isLogin = true
    } else {
    state.isLogin = false
    }
    }

    当调用 initializeStore mutation 时,它会检查本地存储中是否存在名为 token 的数据。如果存在,则将 state.isLogin 设置为 true,表示用户已登录;否则,将其设置为 false,表示用户未登录。

    当调用 setLoginStatus mutation 时,它接收一个布尔值 status 作为参数,并将 state.isLogin 设置为传入的状态值。这用于在其他地方(例如登录组件)更新用户的登录状态。

这个 Vuex store 的配置简单地管理了一个表示用户登录状态的状态变量,并提供了两个 mutations 用于初始化和更新该状态。

在创建组件前判断登录状态

每次访问页面时,我们需要判断用户的登录状态,可以在Mutations中添加一个方法,我们将其命名为InitializeStore

frontend/src/App.vue
<template>
<router-view/>
</template>

<script>
import axios from 'axios'

export default {
name: 'App',
beforeCreate() {
this.$store.commit('initializeStore')
},
}
</script>
代码解析
  • name: 'App': 设置组件的名称为 "App"。
  • beforeCreate() { ... }: 这是一个生命周期钩子函数,会在组件实例被创建之前调用。在这里,使用了 this.$store.commit('initializeStore') 来触发 Vuex store 中名为 initializeStore 的 mutation。

综合起来,这个主组件主要负责渲染子组件,而在组件创建之前通过 Vuex 的 initializeStore mutation 初始化应用的状态,确保在应用加载时处理了用户的登录状态。

在页面中根据登录状态进行显示

在页面中,我们可以根据用户的登录状态来显示不同的内容。例如,在Header组件中,我们可以根据登录状态来显示"登录/注册"或者"用户名"。 Header.vue代码是如下:

frontend/src/components/Header.vue
<template>
<!-- 登录和注册 -->
<div v-if="$store.state.isLogin">{{ username }}</div>
<div v-else class="text-white flex-shrink-0 pr-2">
<a href="#">登录</a>
/ <a href="#">注册</a>
</div>
</template>

<script>
import Category from "./Category.vue";
export default {
components: { Category },
name: "Header",
data() {
return { keyword: "", username: "" };
},
mounted() {
// 从本地获取用户名
this.username = localStorage.getItem("username");
// 判断登录状态
const currentTime = Date.now();
const expiredTime = localStorage.getItem("expiredTime");

if (expiredTime > currentTime) {
this.$store.commit("setLoginStatus", true);
} else {
this.$store.commit("setLoginStatus", false);
}
},

};
</script>

代码解析
  • v-if="$store.state.isLogin": 使用 Vue 的条件渲染,当 Vuex store 中的 isLogin 状态为 true 时,显示用户的用户名。

  • {{ username }}: 在登录状态下,显示用户的用户名。

  • v-else: 如果用户未登录,则显示登录和注册的链接。

  • <a href="#">登录</a> / <a href="#">注册</a>: 显示登录和注册的链接,这里的 href 属性值是 "#",意味着点击这些链接不会导致页面跳转。

  • import Category from "./Category.vue";: 导入名为 Category 的组件,但在当前组件的模板中并没有使用。

  • components: { Category },: 注册了一个局部组件 Category

  • name: "Header",: 设置组件的名称为 "Header"。

  • data() { return { keyword: "", username: "" }; },: 定义了组件的数据,包括 keywordusername

  • mounted() { ... }: 生命周期钩子函数 mounted,在组件挂载到 DOM 后执行。在这里进行了一些初始化操作:

  • 从本地存储获取用户的用户名,并将其存储在 this.username 中。

  • 获取本地存储中的 expiredTime 和当前时间,判断用户是否处于登录状态,并通过调用 $store.commit("setLoginStatus", true/false) 来更新 Vuex store 中的登录状态。

总体来说,这个组件根据用户是否登录显示不同的内容,并在组件挂载时初始化用户的登录状态。

此外,还需要在登录成功时,设置过期时间为5分钟,代码如下:

frontend/src/views/Login.vue

localStorage.setItem("token", token);
localStorage.setItem("refreshToken", refreshToken);
localStorage.setItem("username", username);
// 新增代码,设置过期时间
localStorage.setItem("expiredTime", Date.now() + 5 * 60 * 1000);

</script>

通过以上操作,我们就可以在页面中根据用户的登录状态进行显示相应的信息了。

图38-登录成功效果

图38-登录过期效果

在下一节课中,我们将讲解当用户的Token过期后,如何在不登录的情况下,使用Refresh Token来刷新Token并更新过期时间。