feat(QrLogin): 将登录源选择器从单选按钮组更改为标签页

将 QrLogin 组件中的登录源选择器从 n-radio-group 替换为 n-tabs,
提供更好的用户体验和视觉效果。移除了相关的 flex 布局样式。

同时更新了组件中使用的 Naive UI 组件导入,添加了 NTabs 和 NTabPane,
并从 components.d.ts 中移除了未使用的全局组件声明。
This commit is contained in:
Yuhang Wu 2026-08-14 17:54:38 +08:00
parent 6593225d0f
commit cdd561a21d
3 changed files with 91 additions and 16 deletions

View File

@ -10,14 +10,20 @@
</div> </div>
<template v-else-if="sources.length > 0"> <template v-else-if="sources.length > 0">
<n-radio-group :value="selectedSource" @update:value="onSelectSource" class="login-sources"> <n-tabs
<n-radio-button :value="selectedSource ?? undefined"
type="segment"
animated
@update:value="onSelectSource"
class="login-sources"
>
<n-tab-pane
v-for="item in sources" v-for="item in sources"
:key="item.source" :key="item.source"
:value="item.source" :name="item.source"
:label="item.name" :tab="item.name"
/> />
</n-radio-group> </n-tabs>
<div class="login-body"> <div class="login-body">
<div class="qr-box"> <div class="qr-box">
@ -56,7 +62,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from "vue" import { computed, onBeforeUnmount, onMounted, ref } from "vue"
import { NButton, NEmpty, NRadioButton, NRadioGroup, NSpin, NTag, useMessage } from "naive-ui" import { NButton, NEmpty, NSpin, NTabPane, NTabs, NTag, useMessage } from "naive-ui"
import QRCode from "qrcode" import QRCode from "qrcode"
import SystemApi, { import SystemApi, {
type QrLoginSession, type QrLoginSession,
@ -238,9 +244,6 @@ function stopPolling() {
} }
.login-sources { .login-sources {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 18px; margin-bottom: 18px;
} }

View File

@ -0,0 +1,79 @@
/* eslint-disable */
/* prettier-ignore */
/* oxlint-disable */
/* oxfmt-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const EffectScope: typeof import('vue').EffectScope
const computed: typeof import('vue').computed
const createApp: typeof import('vue').createApp
const customRef: typeof import('vue').customRef
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
const defineComponent: typeof import('vue').defineComponent
const effectScope: typeof import('vue').effectScope
const getCurrentInstance: typeof import('vue').getCurrentInstance
const getCurrentScope: typeof import('vue').getCurrentScope
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
const h: typeof import('vue').h
const inject: typeof import('vue').inject
const isProxy: typeof import('vue').isProxy
const isReactive: typeof import('vue').isReactive
const isReadonly: typeof import('vue').isReadonly
const isRef: typeof import('vue').isRef
const isShallow: typeof import('vue').isShallow
const markRaw: typeof import('vue').markRaw
const nextTick: typeof import('vue').nextTick
const onActivated: typeof import('vue').onActivated
const onBeforeMount: typeof import('vue').onBeforeMount
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
const onDeactivated: typeof import('vue').onDeactivated
const onErrorCaptured: typeof import('vue').onErrorCaptured
const onMounted: typeof import('vue').onMounted
const onRenderTracked: typeof import('vue').onRenderTracked
const onRenderTriggered: typeof import('vue').onRenderTriggered
const onScopeDispose: typeof import('vue').onScopeDispose
const onServerPrefetch: typeof import('vue').onServerPrefetch
const onUnmounted: typeof import('vue').onUnmounted
const onUpdated: typeof import('vue').onUpdated
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
const provide: typeof import('vue').provide
const reactive: typeof import('vue').reactive
const readonly: typeof import('vue').readonly
const ref: typeof import('vue').ref
const resolveComponent: typeof import('vue').resolveComponent
const shallowReactive: typeof import('vue').shallowReactive
const shallowReadonly: typeof import('vue').shallowReadonly
const shallowRef: typeof import('vue').shallowRef
const toRaw: typeof import('vue').toRaw
const toRef: typeof import('vue').toRef
const toRefs: typeof import('vue').toRefs
const toValue: typeof import('vue').toValue
const triggerRef: typeof import('vue').triggerRef
const unref: typeof import('vue').unref
const useAttrs: typeof import('vue').useAttrs
const useCssModule: typeof import('vue').useCssModule
const useCssVars: typeof import('vue').useCssVars
const useDialog: typeof import('naive-ui').useDialog
const useId: typeof import('vue').useId
const useLoadingBar: typeof import('naive-ui').useLoadingBar
const useMessage: typeof import('naive-ui').useMessage
const useModel: typeof import('vue').useModel
const useNotification: typeof import('naive-ui').useNotification
const useSlots: typeof import('vue').useSlots
const useTemplateRef: typeof import('vue').useTemplateRef
const watch: typeof import('vue').watch
const watchEffect: typeof import('vue').watchEffect
const watchPostEffect: typeof import('vue').watchPostEffect
const watchSyncEffect: typeof import('vue').watchSyncEffect
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}

View File

@ -14,19 +14,12 @@ declare module 'vue' {
AppIcon: typeof import('./../components/AppIcon.vue')['default'] AppIcon: typeof import('./../components/AppIcon.vue')['default']
FullscreenPlayer: typeof import('./../components/FullscreenPlayer.vue')['default'] FullscreenPlayer: typeof import('./../components/FullscreenPlayer.vue')['default']
MusicCard: typeof import('./../components/MusicCard.vue')['default'] MusicCard: typeof import('./../components/MusicCard.vue')['default']
NBackTop: typeof import('naive-ui')['NBackTop']
NButton: typeof import('naive-ui')['NButton']
NCheckbox: typeof import('naive-ui')['NCheckbox'] NCheckbox: typeof import('naive-ui')['NCheckbox']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NIcon: typeof import('naive-ui')['NIcon']
NLayout: typeof import('naive-ui')['NLayout'] NLayout: typeof import('naive-ui')['NLayout']
NLayoutContent: typeof import('naive-ui')['NLayoutContent'] NLayoutContent: typeof import('naive-ui')['NLayoutContent']
NLayoutFooter: typeof import('naive-ui')['NLayoutFooter'] NLayoutFooter: typeof import('naive-ui')['NLayoutFooter']
NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NRadio: typeof import('naive-ui')['NRadio'] NRadio: typeof import('naive-ui')['NRadio']
PlayerBar: typeof import('./../components/PlayerBar.vue')['default'] PlayerBar: typeof import('./../components/PlayerBar.vue')['default']
QrLogin: typeof import('./../components/QrLogin.vue')['default'] QrLogin: typeof import('./../components/QrLogin.vue')['default']