Compare commits

...

5 Commits

Author SHA1 Message Date
Tim
bf169932b3 refactor: use iconpark in dropdown 2025-09-06 10:07:19 +08:00
Tim
4a4c256568 Merge pull request #892 from nagisa77/codex/adapt-basetabs-to-use-iconpark
feat: use iconpark in base tabs
2025-09-06 01:42:43 +08:00
Tim
3bb14ca6a3 feat: use iconpark in base tabs 2025-09-06 01:42:15 +08:00
Tim
4ed679c4f4 Merge pull request #890 from nagisa77/codex/adapt-menucomponent-and-headercomponent-for-iconpark
refactor: support iconpark in menu and header
2025-09-05 22:22:18 +08:00
tim
51819913a0 feat: user info page 2025-09-05 22:18:57 +08:00
4 changed files with 70 additions and 14 deletions

View File

@@ -8,7 +8,12 @@
:class="['base-tabs-item', { selected: modelValue === tab.key }]"
@click="$emit('update:modelValue', tab.key)"
>
<i v-if="tab.icon" :class="tab.icon"></i>
<component
v-if="tab.icon && (typeof tab.icon !== 'string' || !tab.icon.includes(' '))"
:is="tab.icon"
class="base-tabs-item-icon"
/>
<i v-else-if="tab.icon" :class="tab.icon"></i>
<div class="base-tabs-item-label">{{ tab.label }}</div>
</div>
</div>
@@ -72,6 +77,7 @@ function onTouchEnd(e) {
align-items: center;
}
.base-tabs-item-icon,
.base-tabs-item i {
margin-right: 6px;
}

View File

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

View File

@@ -18,7 +18,7 @@
class="profile-page-header-subscribe-button"
@click="subscribeUser"
>
<i class="fas fa-user-plus"></i>
<add-user />
关注
</div>
<div
@@ -26,11 +26,11 @@
class="profile-page-header-unsubscribe-button"
@click="unsubscribeUser"
>
<i class="fas fa-user-minus"></i>
<reduce-user />
取消关注
</div>
<div v-if="!isMine" class="profile-page-header-subscribe-button" @click="sendMessage">
<i class="fas fa-paper-plane"></i>
<message-one />
发私信
</div>
</div>
@@ -45,7 +45,7 @@
content="经验值可通过发帖、评论等操作获得,达到目标后即可提升等级,解锁更多功能。"
placement="bottom"
>
<i class="fas fa-info-circle profile-exp-info"></i>
<info class="profile-exp-info" />
</ToolTip>
</div>
</div>
@@ -368,11 +368,11 @@ const selectedTab = ref(
: 'summary',
)
const tabs = [
{ key: 'summary', label: '总结', icon: 'fas fa-chart-line' },
{ key: 'timeline', label: '时间线', icon: 'fas fa-clock' },
{ key: 'following', label: '关注', icon: 'fas fa-user-plus' },
{ key: 'favorites', label: '收藏', icon: 'fas fa-bookmark' },
{ key: 'achievements', label: '勋章', icon: 'fas fa-medal' },
{ key: 'summary', label: '总结', icon: 'ChartLine' },
{ key: 'timeline', label: '时间线', icon: 'AlarmClock' },
{ key: 'following', label: '关注', icon: 'AddUser' },
{ key: 'favorites', label: '收藏', icon: 'Bookmark' },
{ key: 'achievements', label: '勋章', icon: 'MedalOne' },
]
const followTab = ref('followers')

View File

@@ -31,6 +31,12 @@ import {
Loading,
Rss,
MessageEmoji,
AddUser,
ReduceUser,
MessageOne,
AlarmClock,
Bookmark,
ArrowLeft,
} from '@icon-park/vue-next'
export default defineNuxtPlugin((nuxtApp) => {
@@ -65,4 +71,10 @@ export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('Loading', Loading)
nuxtApp.vueApp.component('Rss', Rss)
nuxtApp.vueApp.component('MessageEmoji', MessageEmoji)
nuxtApp.vueApp.component('AddUser', AddUser)
nuxtApp.vueApp.component('ReduceUser', ReduceUser)
nuxtApp.vueApp.component('MessageOne', MessageOne)
nuxtApp.vueApp.component('AlarmClock', AlarmClock)
nuxtApp.vueApp.component('Bookmark', Bookmark)
nuxtApp.vueApp.component('ArrowLeft', ArrowLeft)
})