通用组件
@udhold/udhold-ui 通用组件参考:消息提示、确认弹窗、下拉框、快捷键录制、滑杆、详情面板与自适应图标。
@udhold/udhold-ui 是官方共享组件库,随官方插件工程仓库分发(workspace:* 引用,见快速上手)。组件按需 import,没有全局注册,样式与令牌体系一体。
引入方式
// 组件
import { Message, ConfirmDialog, Dropdown, Slider } from '@udhold/udhold-ui/components/common'
// 或分别引:'@udhold/udhold-ui/components/Message'
// 组合式函数与工具
import { useMessage } from '@udhold/udhold-ui/components/common'
import { useColorScheme } from '@udhold/udhold-ui/composables'
Message:全局消息提示
挂载一次,全局调用。 根组件里挂容器(useMessage() 返回的响应式状态接给组件),之后任何地方 useMessage() 直接弹消息:
<script setup lang="ts">
// App.vue —— 挂载容器
import { Message, ConfirmDialog, useMessage } from '@udhold/udhold-ui/components/common'
const { messageState, handleClose, handleAction, confirmState, handleConfirm, handleCancel } = useMessage()
</script>
<template>
<div id="app"><!-- 页面内容 --></div>
<Message :items="messageState" @close="handleClose" @action-click="handleAction" />
</template>
// 任何业务组件里
import { useMessage } from '@udhold/udhold-ui/components/common'
const message = useMessage()
message.success('已复制颜色 #2f6fec')
message.error('导出失败:文件被占用')
message.warning('列表已过期,正在刷新')
message.info('已切换到紧凑模式')
| 参数 | 说明 |
|---|---|
type | success / error / warning / info / primary,对应语义前置圆点 |
duration | 停留时长,默认 3000ms |
position | top / bottom |
ConfirmDialog:确认弹窗
与 useMessage() 同源,命令式调用,返回 Promise——不用自己管理弹窗状态:
const { confirm, confirmWithExtra, alert } = useMessage()
// 二选一确认
const ok: boolean = await confirm({
title: '删除记录',
message: '删除后不可恢复,确定删除这 3 条记录吗?',
type: 'danger', // info / warning / danger,控制确认按钮风格
confirmText: '删除'
})
if (ok) { /* 执行删除 */ }
// 带附加复选项(如「同时删除云端数据」)
const result = await confirmWithExtra({
title: '卸载插件',
message: '将删除插件及其全部数据。',
type: 'danger',
extra: [{ id: 'keepData', message: '保留插件数据', defaultChecked: false }]
})
// result.confirmed: boolean, result.extra: { keepData: boolean }
// 纯提示(单按钮)
await alert({ title: '导入完成', message: '共导入 128 条记录。' })
容器同样在根组件挂一次:<ConfirmDialog v-model:visible="confirmState.visible" ... />,模板见上面 Message 的 App.vue 示例。
Dropdown:下拉选择
原生 select 的样式化封装(弹出面板跟随系统明暗):
<script setup lang="ts">
import { ref } from 'vue'
import { Dropdown } from '@udhold/udhold-ui/components/common'
const sort = ref('time')
const options = [
{ label: '按时间排序', value: 'time' },
{ label: '按名称排序', value: 'name' }
]
</script>
<template>
<Dropdown v-model="sort" :options="options" placeholder="选择排序方式" />
</template>
HotkeyInput:快捷键录制
点击进入录制态,按下组合键即完成录入,支持修饰键组合(含 400ms 内双击同一修饰键,如 Ctrl+Ctrl)与 F1–F12:
<script setup lang="ts">
import { ref } from 'vue'
import { HotkeyInput } from '@udhold/udhold-ui/components/common'
const hotkey = ref('Ctrl+Alt+P')
</script>
<template>
<HotkeyInput v-model="hotkey" placeholder="点击录制快捷键" />
</template>
优先走宿主后端录制(结果与全局快捷键注册系统一致),宿主不支持时自动回退前端按键监听;不支持的按键会以 toast 提示。
Slider:滑杆
<Slider v-model="opacity" :min="30" :max="100" :step="5" :formatter="v => v + '%'" />
轨道已按主色渐变渲染,无需额外样式。
DetailPanel:二级详情面板
覆盖在内容区上方的二级页面(无遮罩、带滑入过渡),配「返回」顶栏——列表页点进详情页的标准形态:
<script setup lang="ts">
import { ref } from 'vue'
import { DetailPanel } from '@udhold/udhold-ui/components/common'
const detailId = ref<string | null>(null)
</script>
<template>
<Transition name="slide">
<DetailPanel v-if="detailId" :title="'详情 #' + detailId" @back="detailId = null">
<template #header-right>
<button class="icon-btn"><span class="i-z-copy w-4 h-4" /></button>
</template>
<!-- 详情内容 -->
</DetailPanel>
</Transition>
</template>
组件自带 slide / slide-reverse 过渡类,供 <Transition> 做一级↔二级切换动画。
AdaptiveIcon:自适应位图图标
位图 logo 在暗色模式下会隐形的痛点,交给它处理:自动分析图片主色,需要时反色:
<AdaptiveIcon :src="provider.logo" alt="服务商图标" class="w-5 h-5" />
懒分析(进入视口前 100px 才开始),forceAdaptive 属性可跳过检测强制暗色反色。
工具函数
@udhold/udhold-ui/utils 里几个高频工具:
| 函数 | 用途 |
|---|---|
setupThemeSync() | 主题联动总入口(主题与明暗模式) |
isDarkMode() | 同步判断当前是否暗色 |
weightedSearch(items, query, fields) | 多字段加权搜索:fields 里给每个字段配权重,命中累加按分数排序,做插件内列表过滤很好用 |
setupPlatformClass() | 给 html 加 os-windows / os-mac / os-linux 类,CSS 里做平台差异适配 |
import { weightedSearch } from '@udhold/udhold-ui/utils'
const result = weightedSearch(commands, keyword, [
{ value: c => c.name, weight: 3 },
{ value: c => c.description, weight: 1 }
])
更高层的场景组件(加载态、搜索列表、代码块、侧边导航)看下一篇场景组件。