index.vue 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <div class="relative flex-center wh-full" :style="{ backgroundColor: bgColor }">
  3. <dark-mode-switch
  4. :dark="theme.darkMode"
  5. class="absolute left-48px top-24px z-3 text-20px"
  6. @update:dark="theme.setDarkMode"
  7. />
  8. <n-card :bordered="false" size="large" class="z-4 !w-auto rounded-20px shadow-sm">
  9. <div class="w-300px sm:w-360px">
  10. <header class="flex-y-center justify-between">
  11. <system-logo class="text-64px text-primary" />
  12. <n-gradient-text type="primary" :size="28">{{ title }}</n-gradient-text>
  13. </header>
  14. <main class="pt-24px">
  15. <h3 class="text-18px text-primary font-medium">{{ activeModule.label }}</h3>
  16. <div class="pt-24px">
  17. <transition name="fade-slide" mode="out-in" appear>
  18. <component :is="activeModule.component" />
  19. </transition>
  20. </div>
  21. </main>
  22. </div>
  23. </n-card>
  24. <login-bg :theme-color="bgThemeColor" />
  25. </div>
  26. </template>
  27. <script setup lang="ts">
  28. import { computed } from 'vue';
  29. import type { Component } from 'vue';
  30. // eslint-disable-next-line import/no-unresolved
  31. import { loginModuleLabels } from '@/constants';
  32. // eslint-disable-next-line import/no-unresolved
  33. import { useThemeStore } from '@/store';
  34. // eslint-disable-next-line import/no-unresolved
  35. import { useAppInfo } from '@/composables';
  36. // eslint-disable-next-line import/no-unresolved
  37. import { getColorPalette, mixColor } from '@/utils';
  38. import { BindWechat, CodeLogin, LoginBg, PwdLogin, Register, ResetPwd } from './components';
  39. interface Props {
  40. /** 登录模块分类 */
  41. module: UnionKey.LoginModule;
  42. }
  43. const props = defineProps<Props>();
  44. const theme = useThemeStore();
  45. const { title } = useAppInfo();
  46. interface LoginModule {
  47. key: UnionKey.LoginModule;
  48. label: string;
  49. component: Component;
  50. }
  51. const modules: LoginModule[] = [
  52. { key: 'pwd-login', label: loginModuleLabels['pwd-login'], component: PwdLogin },
  53. { key: 'code-login', label: loginModuleLabels['code-login'], component: CodeLogin },
  54. { key: 'register', label: loginModuleLabels.register, component: Register },
  55. { key: 'reset-pwd', label: loginModuleLabels['reset-pwd'], component: ResetPwd },
  56. { key: 'bind-wechat', label: loginModuleLabels['bind-wechat'], component: BindWechat }
  57. ];
  58. const activeModule = computed(() => {
  59. const active: LoginModule = { ...modules[0] };
  60. const findItem = modules.find(item => item.key === props.module);
  61. if (findItem) {
  62. Object.assign(active, findItem);
  63. }
  64. return active;
  65. });
  66. const bgThemeColor = computed(() => (theme.darkMode ? getColorPalette(theme.themeColor, 7) : theme.themeColor));
  67. const bgColor = computed(() => {
  68. const COLOR_WHITE = '#ffffff';
  69. const ratio = theme.darkMode ? 0.5 : 0.2;
  70. return mixColor(COLOR_WHITE, theme.themeColor, ratio);
  71. });
  72. </script>
  73. <style scoped></style>