Skip to content

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滚动到上一项
canScrollNextRef<boolean>是否可向后滚动
canScrollPrevRef<boolean>是否可向前滚动
carouselApiRef<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>

基于 MIT 协议发布(内部使用)