fix: 退出登录补防抖加载
This commit is contained in:
@@ -69,4 +69,25 @@ describe('MyHead.vue', () => {
|
|||||||
expect(ElMessage.success).toHaveBeenCalledWith('已退出登录')
|
expect(ElMessage.success).toHaveBeenCalledWith('已退出登录')
|
||||||
expect(router.currentRoute.value.path).toBe('/login')
|
expect(router.currentRoute.value.path).toBe('/login')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('prevents repeated logout while request is pending', async () => {
|
||||||
|
let resolveLogout!: (value: any) => void
|
||||||
|
vi.mocked(logout).mockImplementation(
|
||||||
|
() => new Promise((resolve) => { resolveLogout = resolve }),
|
||||||
|
)
|
||||||
|
localStorage.setItem('isLoggedIn', 'true')
|
||||||
|
const wrapper = await mountAt('/study')
|
||||||
|
|
||||||
|
const first = wrapper.vm.handleLogout()
|
||||||
|
const second = wrapper.vm.handleLogout()
|
||||||
|
await Promise.resolve()
|
||||||
|
|
||||||
|
expect(logout).toHaveBeenCalledTimes(1)
|
||||||
|
expect(wrapper.vm.loggingOut).toBe(true)
|
||||||
|
|
||||||
|
resolveLogout({ code: 200 })
|
||||||
|
await Promise.all([first, second])
|
||||||
|
|
||||||
|
expect(wrapper.vm.loggingOut).toBe(false)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
type="success"
|
type="success"
|
||||||
plain
|
plain
|
||||||
class="logout-btn"
|
class="logout-btn"
|
||||||
|
:loading="loggingOut"
|
||||||
@click="handleLogout"
|
@click="handleLogout"
|
||||||
>
|
>
|
||||||
退出登录
|
退出登录
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
@@ -38,20 +39,26 @@ const route = useRoute();
|
|||||||
const isLoginRoute = computed(() => route.path === "/login");
|
const isLoginRoute = computed(() => route.path === "/login");
|
||||||
const showBackButton = computed(() => route.path !== "/login" && route.path !== "/welcome");
|
const showBackButton = computed(() => route.path !== "/login" && route.path !== "/welcome");
|
||||||
const pageTitle = computed(() => route.meta?.title as string | undefined);
|
const pageTitle = computed(() => route.meta?.title as string | undefined);
|
||||||
|
const loggingOut = ref(false);
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
|
if (loggingOut.value) return;
|
||||||
|
loggingOut.value = true;
|
||||||
try {
|
try {
|
||||||
await logout();
|
try {
|
||||||
} catch {
|
await logout();
|
||||||
// 后端退出失败时,仍然清理前端登录态,避免用户被卡住。
|
} catch {
|
||||||
} finally {
|
// 后端退出失败时,仍然清理前端登录态,避免用户被卡住。
|
||||||
|
}
|
||||||
localStorage.removeItem("isLoggedIn");
|
localStorage.removeItem("isLoggedIn");
|
||||||
ElMessage.success("已退出登录");
|
ElMessage.success("已退出登录");
|
||||||
await router.push("/login");
|
await router.push("/login");
|
||||||
|
} finally {
|
||||||
|
loggingOut.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({ isLoginRoute, showBackButton, pageTitle, handleLogout });
|
defineExpose({ isLoginRoute, showBackButton, pageTitle, loggingOut, handleLogout });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user