Compare commits

..

1 Commits

Author SHA1 Message Date
Tim
bf169932b3 refactor: use iconpark in dropdown 2025-09-06 10:07:19 +08:00
7 changed files with 63 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="base-input"> <div class="base-input">
<component v-if="icon" :is="icon" class="base-input-icon" size="14" /> <i v-if="icon" :class="['base-input-icon', icon]" />
<!-- 普通输入框 --> <!-- 普通输入框 -->
<input <input
@@ -29,7 +29,7 @@ export default {
inheritAttrs: false, inheritAttrs: false,
props: { props: {
modelValue: { type: [String, Number], default: '' }, modelValue: { type: [String, Number], default: '' },
icon: { type: [String, Object], default: '' }, icon: { type: String, default: '' },
type: { type: String, default: 'text' }, type: { type: String, default: 'text' },
textarea: { type: Boolean, default: false }, textarea: { type: Boolean, default: false },
}, },
@@ -66,6 +66,7 @@ export default {
.base-input-icon { .base-input-icon {
opacity: 0.5; opacity: 0.5;
font-size: 14px;
} }
.base-input-text { .base-input-text {

View File

@@ -19,6 +19,14 @@
class="option-icon" class="option-icon"
:alt="label.name" :alt="label.name"
/> />
<component
v-else-if="isIconComponent(label.icon)"
:is="label.icon"
class="option-icon"
theme="outline"
size="16"
fill="currentColor"
/>
<i v-else :class="['option-icon', label.icon]"></i> <i v-else :class="['option-icon', label.icon]"></i>
</template> </template>
<span>{{ label.name }}</span> <span>{{ label.name }}</span>
@@ -38,6 +46,14 @@
class="option-icon" class="option-icon"
:alt="selectedLabels[0].name" :alt="selectedLabels[0].name"
/> />
<component
v-else-if="isIconComponent(selectedLabels[0].icon)"
:is="selectedLabels[0].icon"
class="option-icon"
theme="outline"
size="16"
fill="currentColor"
/>
<i v-else :class="['option-icon', selectedLabels[0].icon]"></i> <i v-else :class="['option-icon', selectedLabels[0].icon]"></i>
</template> </template>
<span>{{ selectedLabels[0].name }}</span> <span>{{ selectedLabels[0].name }}</span>
@@ -45,7 +61,7 @@
</span> </span>
<span v-else class="placeholder">{{ placeholder }}</span> <span v-else class="placeholder">{{ placeholder }}</span>
</template> </template>
<i class="fas fa-caret-down dropdown-caret"></i> <Down class="dropdown-caret" theme="outline" size="16" fill="currentColor" />
</slot> </slot>
</div> </div>
<div <div
@@ -54,7 +70,7 @@
v-click-outside="close" v-click-outside="close"
> >
<div v-if="showSearch" class="dropdown-search"> <div v-if="showSearch" class="dropdown-search">
<i class="fas fa-search search-icon"></i> <SearchIcon class="search-icon" theme="outline" size="16" fill="currentColor" />
<input type="text" v-model="search" placeholder="搜索" /> <input type="text" v-model="search" placeholder="搜索" />
</div> </div>
<div v-if="loading" class="dropdown-loading"> <div v-if="loading" class="dropdown-loading">
@@ -75,6 +91,14 @@
class="option-icon" class="option-icon"
:alt="o.name" :alt="o.name"
/> />
<component
v-else-if="isIconComponent(o.icon)"
:is="o.icon"
class="option-icon"
theme="outline"
size="16"
fill="currentColor"
/>
<i v-else :class="['option-icon', o.icon]"></i> <i v-else :class="['option-icon', o.icon]"></i>
</template> </template>
<span>{{ o.name }}</span> <span>{{ o.name }}</span>
@@ -85,12 +109,12 @@
<Teleport to="body"> <Teleport to="body">
<div v-if="open && isMobile" class="dropdown-mobile-page"> <div v-if="open && isMobile" class="dropdown-mobile-page">
<div class="dropdown-mobile-header"> <div class="dropdown-mobile-header">
<i class="fas fa-arrow-left" @click="close"></i> <ArrowLeft @click="close" theme="outline" size="16" fill="currentColor" />
<span class="mobile-title">{{ placeholder }}</span> <span class="mobile-title">{{ placeholder }}</span>
</div> </div>
<div class="dropdown-mobile-menu"> <div class="dropdown-mobile-menu">
<div v-if="showSearch" class="dropdown-search"> <div v-if="showSearch" class="dropdown-search">
<i class="fas fa-search search-icon"></i> <SearchIcon class="search-icon" theme="outline" size="16" fill="currentColor" />
<input type="text" v-model="search" placeholder="搜索" /> <input type="text" v-model="search" placeholder="搜索" />
</div> </div>
<div v-if="loading" class="dropdown-loading"> <div v-if="loading" class="dropdown-loading">
@@ -111,6 +135,14 @@
class="option-icon" class="option-icon"
:alt="o.name" :alt="o.name"
/> />
<component
v-else-if="isIconComponent(o.icon)"
:is="o.icon"
class="option-icon"
theme="outline"
size="16"
fill="currentColor"
/>
<i v-else :class="['option-icon', o.icon]"></i> <i v-else :class="['option-icon', o.icon]"></i>
</template> </template>
<span>{{ o.name }}</span> <span>{{ o.name }}</span>
@@ -249,6 +281,11 @@ export default {
return /^https?:\/\//.test(icon) || icon.startsWith('/') return /^https?:\/\//.test(icon) || icon.startsWith('/')
} }
const isIconComponent = (icon) => {
if (!icon) return false
return !icon.includes(' ')
}
expose({ toggle, close }) expose({ toggle, close })
return { return {
@@ -263,6 +300,7 @@ export default {
isSelected, isSelected,
loading, loading,
isImageIcon, isImageIcon,
isIconComponent,
setSearch, setSearch,
isMobile, isMobile,
} }

View File

@@ -2,20 +2,20 @@
<div class="forgot-page"> <div class="forgot-page">
<div class="forgot-content"> <div class="forgot-content">
<div class="forgot-title">找回密码</div> <div class="forgot-title">找回密码</div>
<div v-if="step === 0" class="step-content"> <div v-if="step === 0" class="step-content">
<BaseInput icon="Mail" v-model="email" placeholder="邮箱" /> <BaseInput icon="fas fa-envelope" v-model="email" placeholder="邮箱" />
<div v-if="emailError" class="error-message">{{ emailError }}</div> <div v-if="emailError" class="error-message">{{ emailError }}</div>
<div class="primary-button" @click="sendCode" v-if="!isSending">发送验证码</div> <div class="primary-button" @click="sendCode" v-if="!isSending">发送验证码</div>
<div class="primary-button disabled" v-else>发送中...</div> <div class="primary-button disabled" v-else>发送中...</div>
</div> </div>
<div v-else-if="step === 1" class="step-content"> <div v-else-if="step === 1" class="step-content">
<BaseInput icon="Mail" v-model="code" placeholder="邮箱验证码" /> <BaseInput icon="fas fa-envelope" v-model="code" placeholder="邮箱验证码" />
<div class="primary-button" @click="verifyCode" v-if="!isVerifying">验证</div> <div class="primary-button" @click="verifyCode" v-if="!isVerifying">验证</div>
<div class="primary-button disabled" v-else>验证中...</div> <div class="primary-button disabled" v-else>验证中...</div>
</div> </div>
<div v-else class="step-content"> <div v-else class="step-content">
<BaseInput icon="Lock" v-model="password" type="password" placeholder="新密码" /> <BaseInput icon="fas fa-lock" v-model="password" type="password" placeholder="新密码" />
<div v-if="passwordError" class="error-message">{{ passwordError }}</div> <div v-if="passwordError" class="error-message">{{ passwordError }}</div>
<div class="primary-button" @click="resetPassword" v-if="!isResetting">重置密码</div> <div class="primary-button" @click="resetPassword" v-if="!isResetting">重置密码</div>
<div class="primary-button disabled" v-else>提交中...</div> <div class="primary-button disabled" v-else>提交中...</div>

View File

@@ -6,9 +6,9 @@
</div> </div>
<div class="email-login-page-content"> <div class="email-login-page-content">
<BaseInput icon="Mail" v-model="username" placeholder="邮箱/用户名" /> <BaseInput icon="fas fa-envelope" v-model="username" placeholder="邮箱/用户名" />
<BaseInput icon="Lock" v-model="password" type="password" placeholder="密码" /> <BaseInput icon="fas fa-lock" v-model="password" type="password" placeholder="密码" />
<div v-if="!isWaitingForLogin" class="login-page-button-primary" @click="submitLogin"> <div v-if="!isWaitingForLogin" class="login-page-button-primary" @click="submitLogin">
<div class="login-page-button-text">登录</div> <div class="login-page-button-text">登录</div>

View File

@@ -23,7 +23,7 @@
</div> </div>
<div class="form-row username-row"> <div class="form-row username-row">
<BaseInput <BaseInput
icon="User" icon="fas fa-user"
v-model="username" v-model="username"
@input="usernameError = ''" @input="usernameError = ''"
placeholder="用户名" placeholder="用户名"

View File

@@ -6,11 +6,16 @@
</div> </div>
<div v-if="emailStep === 0" class="email-signup-page-content"> <div v-if="emailStep === 0" class="email-signup-page-content">
<BaseInput icon="Mail" v-model="email" @input="emailError = ''" placeholder="邮箱" /> <BaseInput
icon="fas fa-envelope"
v-model="email"
@input="emailError = ''"
placeholder="邮箱"
/>
<div v-if="emailError" class="error-message">{{ emailError }}</div> <div v-if="emailError" class="error-message">{{ emailError }}</div>
<BaseInput <BaseInput
icon="User" icon="fas fa-user"
v-model="username" v-model="username"
@input="usernameError = ''" @input="usernameError = ''"
placeholder="用户名" placeholder="用户名"
@@ -18,7 +23,7 @@
<div v-if="usernameError" class="error-message">{{ usernameError }}</div> <div v-if="usernameError" class="error-message">{{ usernameError }}</div>
<BaseInput <BaseInput
icon="Lock" icon="fas fa-lock"
v-model="password" v-model="password"
@input="passwordError = ''" @input="passwordError = ''"
type="password" type="password"
@@ -46,7 +51,7 @@
</div> </div>
<div v-if="emailStep === 1" class="email-signup-page-content"> <div v-if="emailStep === 1" class="email-signup-page-content">
<BaseInput icon="Mail" v-model="code" placeholder="邮箱验证码" /> <BaseInput icon="fas fa-envelope" v-model="code" placeholder="邮箱验证码" />
<div <div
v-if="!isWaitingForEmailVerified" v-if="!isWaitingForEmailVerified"
class="signup-page-button-primary" class="signup-page-button-primary"

View File

@@ -36,9 +36,7 @@ import {
MessageOne, MessageOne,
AlarmClock, AlarmClock,
Bookmark, Bookmark,
Mail, ArrowLeft,
Lock,
User,
} from '@icon-park/vue-next' } from '@icon-park/vue-next'
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
@@ -78,7 +76,5 @@ export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('MessageOne', MessageOne) nuxtApp.vueApp.component('MessageOne', MessageOne)
nuxtApp.vueApp.component('AlarmClock', AlarmClock) nuxtApp.vueApp.component('AlarmClock', AlarmClock)
nuxtApp.vueApp.component('Bookmark', Bookmark) nuxtApp.vueApp.component('Bookmark', Bookmark)
nuxtApp.vueApp.component('Mail', Mail) nuxtApp.vueApp.component('ArrowLeft', ArrowLeft)
nuxtApp.vueApp.component('Lock', Lock)
nuxtApp.vueApp.component('User', User)
}) })