Helpers & Composables
除了组件,@tripo3d/design 还导出若干工具函数与 composable。Nuxt 项目均自动导入,Vue 3 项目按需 import 即可。
cn
合并 class,内部使用 clsx + 扩展版 tailwind-merge,正确处理 UnoCSS / Tailwind 工具类的冲突(如 px-4 px-6 保留后者)。
| 签名 | 类型 | 说明 |
|---|---|---|
cn | (...classes: ClassValue[]) => string | 合并任意数量的 class 片段,自动去重/后胜 |
vue
<script setup lang="ts">
import { cn } from '@tripo3d/design';
const props = defineProps<{ class?: string; active?: boolean }>();
const cls = cn('px-4 py-2', props.active && 'bg-yellow-400', props.class);
</script>dialog(命令式)
用于在非模板上下文(事件处理、工具函数)打开弹窗。依赖 <DialogOpener> 已挂载在应用根部(Nuxt 自动;Vue 3 需手动)。
| 方法 | 签名 | 说明 |
|---|---|---|
dialog.show | (Component, params?) => key | 打开任意组件作为弹窗,返回唯一 key |
dialog.update | (key, params?) => void | 更新已打开弹窗的 props |
dialog.close | (key) => void | 关闭弹窗(带 150ms 退场动画) |
vue
<script setup lang="ts">
import { dialog } from '@tripo3d/design';
import MySettingsPanel from './MySettingsPanel.vue';
const key = dialog.show(MySettingsPanel, { initialTab: 'profile' });
// 3 秒后自动关闭
setTimeout(() => dialog.close(key), 3000);
</script>详见 Dialog。
loading(命令式)
全屏 Loading 遮罩,委托给 dialog 原语,默认渲染 Loading 组件。
| 方法 | 签名 | 说明 |
|---|---|---|
loading.show | (dialog?, params?) => key | 显示 Loading,可自定义渲染组件 |
loading.update | (key, params?) => void | 更新 Loading 内容 |
loading.close | (key) => void | 关闭 Loading |
vue
<script setup lang="ts">
import { loading, toast } from '@tripo3d/design';
async function handleUpload() {
const key = loading.show();
try {
await uploadFiles(files);
toast.success('上传成功');
} finally {
loading.close(key);
}
}
</script>useDialog
在命令式打开的弹窗子组件中获取 close 方法,无需通过 emit 层层传递。
| 字段 | 类型 | 说明 |
|---|---|---|
close | () => void | 关闭当前弹窗 |
vue
<script setup lang="ts">
import { useDialog } from '@tripo3d/design';
const { close } = useDialog();
</script>
<template>
<button @click="close">关闭自己</button>
</template>useCarousel
在 <Carousel> 默认 slot 作用域或子组件中控制轮播状态。
| 字段 | 类型 | 说明 |
|---|---|---|
orientation | 'horizontal' | 'vertical' | 当前方向 |
scrollNext | () => void | 滚动到下一项 |
scrollPrev | () => void | 滚动到上一项 |
canScrollNext | Ref<boolean> | 是否可向后滚动 |
canScrollPrev | Ref<boolean> | 是否可向前滚动 |
carouselApi | Ref<EmblaCarouselType> | Embla 原始 API,用于高级控制 |
vue
<script setup lang="ts">
import { useCarousel } from '@tripo3d/design';
const { scrollNext, scrollPrev, canScrollNext } = useCarousel();
</script>详见 Carousel。
toast
基于 vue-sonner 的 toast API。详见 Toaster。
常见模式
Opener 模式(命令式弹窗)
vue
<script setup lang="ts">
import { dialog, useDialog } from '@tripo3d/design';
// 1. 打开任意组件作为弹窗
const key = dialog.show(MyComponent, { propA: 'value' });
// 2. 动态更新 props
dialog.update(key, { propA: 'new' });
// 3. 主动关闭
dialog.close(key);
// 4. 或在 MyComponent 内部关闭自己:
// const { close } = useDialog();
</script>链式 class 合并
vue
<script setup lang="ts">
import { cn } from '@tripo3d/design';
const props = defineProps<{
size?: 'sm' | 'md' | 'lg';
variant?: 'solid' | 'outline';
class?: string;
}>();
const cls = cn(
'rounded-6 transition',
{
'px-3 h-8': props.size === 'sm',
'px-4 h-10': props.size === 'md',
'px-6 h-12': props.size === 'lg',
},
props.variant === 'outline' && 'border border-purple-1',
props.class, // 允许外部覆写最终落位
);
</script>