npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mscpore-vue/ui

v1.0.3

Published

@mscpore-vue ui library

Readme

@mscpore-vue/ui

基于 Vue 3 + TypeScript 的现代化 UI 组件库,遵循 MSCPO 设计语言。

特性

  • 基于 Vue 3 Composition API + <script setup> 构建
  • 完整的 TypeScript 类型定义
  • 支持全局引入和按需引入
  • SCSS 设计令牌体系,支持主题定制
  • 良好的可访问性(ARIA 属性、键盘导航)
  • Monorepo + Turborepo 管理

安装

# npm
npm install @mscpore-vue/ui

# yarn
yarn add @mscpore-vue/ui

# pnpm
pnpm add @mscpore-vue/ui

Peer 依赖: Vue >= 3.3

快速开始

全局引入

注册所有组件:

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import VUI from '@mscpore-vue/ui';
import '@mscpore-vue/ui/style.css';

const app = createApp(App);
app.use(VUI);
app.mount('#app');

按需引入

只注册需要的组件:

<script setup lang="ts">
import { VButton, VInput, VCard } from '@mscpore-vue/ui';
import '@mscpore-vue/ui/style.css';
</script>

<template>
  <VButton variant="ore-green">确认</VButton>
  <VInput placeholder="请输入" />
</template>

自动导入(可选)

配合 unplugin-vue-components 实现自动按需注册:

// vite.config.ts
import Components from 'unplugin-vue-components/vite';

export default {
  plugins: [
    Components({
      resolvers: [/* 你的 resolver */],
    }),
  ],
};

组件列表

| 分类 | 组件 | |------|------| | 布局 | Container, Grid, Divider | | 排版 | Heading, Tag, Badge | | 交互 | Button, Input, SearchInput, FloatButton, SocialButton | | 数据展示 | Avatar, AvatarGroup, Card, StatCard, FeatureCard, Skeleton | | 反馈 | Alert, Progress, Empty, Tooltip, ErrorBoundary | | 聊天/消息 | Bubble, Message, MessageScroller, Marker, Attachment | | 导航 | Tabs, Tab, TabsList, TabPanel | | 展示 | HeroBanner, Dialog |


组件 API

Button 按钮

基础按钮组件,支持多种视觉风格。

<template>
  <VButton variant="ore-dark">默认按钮</VButton>
  <VButton variant="ore-green" @click="handleClick">提交</VButton>
  <VButton variant="ore-purple" disabled>禁用</VButton>
  <VButton variant="ore-green" full-width>全宽按钮</VButton>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'ore-dark' \| 'ore-green' \| 'ore-purple' | 'ore-dark' | 视觉风格 | | fullWidth | boolean | false | 是否占满容器宽度 | | disabled | boolean | false | 是否禁用 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | click | (event: MouseEvent) | 点击时触发,禁用时不触发 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 按钮内容 |


Input 输入框

支持前缀/后缀插槽的输入框。

<template>
  <!-- 基础用法 -->
  <VInput v-model="value" placeholder="请输入" />

  <!-- 带前缀 -->
  <VInput v-model="value" placeholder="搜索">
    <template #prefix>🔍</template>
  </VInput>

  <!-- 带后缀 -->
  <VInput v-model="value" placeholder="网址">
    <template #suffix>.com</template>
  </VInput>

  <!-- 不同尺寸 -->
  <VInput v-model="value" size="sm" />
  <VInput v-model="value" size="md" />
  <VInput v-model="value" size="lg" />

  <!-- 错误状态 -->
  <VInput v-model="value" error />
</template>

<script setup lang="ts">
import { ref } from 'vue';
const value = ref('');
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | string | '' | 绑定值(支持 v-model) | | size | 'sm' \| 'md' \| 'lg' | 'md' | 输入框尺寸 | | fullWidth | boolean | false | 是否占满容器宽度 | | error | boolean | false | 错误状态 | | disabled | boolean | false | 是否禁用 | | placeholder | string | — | 占位文本 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | update:modelValue | (value: string) | 输入值变化时触发 |

Slots

| 插槽名 | 说明 | |--------|------| | prefix | 输入框前缀内容 | | suffix | 输入框后缀内容 |


SearchInput 搜索输入框

带搜索图标的输入框。

<template>
  <VSearchInput v-model="keyword" placeholder="搜索..." />
  <VSearchInput v-model="keyword">
    <template #icon>🔍</template>
  </VSearchInput>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const keyword = ref('');
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | string | '' | 绑定值(支持 v-model) | | placeholder | string | '搜索...' | 占位文本 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | update:modelValue | (value: string) | 输入值变化时触发 |

Slots

| 插槽名 | 说明 | |--------|------| | icon | 自定义搜索图标 |


Dialog 对话框

模态对话框,自动 teleport 到 <body>

<template>
  <VButton @click="open = true">打开对话框</VButton>
  <VDialog v-model:open="open" title="提示" :width="480">
    <p>这是一段内容</p>
    <template #footer>
      <VButton variant="ore-dark" @click="open = false">取消</VButton>
      <VButton variant="ore-green" @click="handleConfirm">确认</VButton>
    </template>
  </VDialog>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const open = ref(false);
const handleConfirm = () => { open.value = false; };
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | open | boolean | false | 是否显示(支持 v-model:open) | | title | string | — | 标题文本 | | closable | boolean | true | 是否显示关闭按钮,点击遮罩是否可关闭 | | width | string \| number | 440 | 对话框宽度,数字类型单位为 px |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | update:open | (value: boolean) | 关闭状态变化时触发 | | close | — | 关闭时触发 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 对话框主体内容 | | footer | 底部操作区 |


Alert 警告提示

<template>
  <VAlert type="info">这是一条信息提示</VAlert>
  <VAlert type="success" title="成功">操作已完成</VAlert>
  <VAlert type="warning" closable @close="handleClose">请注意</VAlert>
  <VAlert type="error">出错了</VAlert>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | 'info' \| 'success' \| 'warning' \| 'error' | 'info' | 警告类型 | | title | string | — | 标题 | | closable | boolean | false | 是否可关闭 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | close | — | 关闭时触发 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 提示内容 |


Progress 进度条

<template>
  <VProgress :percent="30" />
  <VProgress :percent="100" status="success" />
  <VProgress :percent="50" status="error" :show-info="false" />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | percent | number | 0 | 进度百分比(0-100,自动 clamp) | | status | 'normal' \| 'success' \| 'error' | 'normal' | 状态 | | showInfo | boolean | true | 是否显示百分比文字 |


Tooltip 文字提示

<template>
  <VTooltip label="这是一段提示文字" placement="top">
    <VButton>Hover me</VButton>
  </VTooltip>
  <VTooltip label="底部提示" placement="bottom">
    <VTag>标签</VTag>
  </VTooltip>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | label | string | — | 提示文本 | | placement | 'top' \| 'bottom' \| 'left' \| 'right' | 'top' | 弹出位置 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 触发元素 |


Empty 空状态

<template>
  <VEmpty description="暂无数据" />
  <VEmpty description="没有找到结果">
    <VButton variant="ore-green">重试</VButton>
  </VEmpty>
  <VEmpty icon="📭" description="消息为空">
    <template #icon>📭</template>
  </VEmpty>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | description | string | 'No data' | 描述文字 | | icon | string | — | 图标(emoji 或文本) |

Slots

| 插槽名 | 说明 | |--------|------| | default | 操作按钮区域 | | icon | 自定义图标 |


ErrorBoundary 错误边界

捕获子组件渲染错误并展示降级 UI。

<template>
  <VErrorBoundary>
    <BrokenComponent />
  </VErrorBoundary>
</template>

组件会自动捕获子组件抛出的错误,显示错误信息。控制台输出 [VErrorBoundary] 前缀的日志。


Avatar 头像

<template>
  <!-- 图片头像 -->
  <VAvatar src="/avatar.jpg" alt="用户头像" size="lg" />

  <!-- 文字回退 -->
  <VAvatar fallback="AB" size="md" />

  <!-- 带状态指示 -->
  <VAvatar
    src="/avatar.jpg"
    size="md"
    status="online"
  />

  <!-- 自定义状态颜色 -->
  <VAvatar fallback="CD" status="online" status-color="#10b981" />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | string | — | 图片地址 | | alt | string | '' | 图片 alt 文本 | | fallback | string | — | 图片加载失败时显示的文字(取前 2 个字符) | | size | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | 尺寸 | | status | 'online' \| 'offline' \| 'away' | — | 状态指示器 | | statusColor | string | — | 状态指示器自定义颜色 |


AvatarGroup 头像组

<template>
  <VAvatarGroup>
    <VAvatar src="/a.jpg" size="sm" />
    <VAvatar src="/b.jpg" size="sm" />
    <VAvatar src="/c.jpg" size="sm" />
  </VAvatarGroup>
</template>

Slots

| 插槽名 | 说明 | |--------|------| | default | 放置多个 VAvatar |


Card 卡片

<template>
  <!-- 基础卡片 -->
  <VCard>
    <VCardBody>卡片内容</VCardBody>
    <VCardFooter>底部操作</VCardFooter>
  </VCard>

  <!-- 可悬浮 -->
  <VCard hoverable>
    <VCardBody>悬浮效果</VCardBody>
  </VCard>

  <!-- 紧凑卡片 -->
  <VCard compact>
    <VCardBody>紧凑间距</VCardBody>
  </VCard>

  <!-- 带背景图的 Feature 卡片 -->
  <VCard feature feature-bg="/bg.jpg">
    <VCardBody>Hover 显示背景</VCardBody>
  </VCard>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | hoverable | boolean | false | 悬浮抬升效果 | | compact | boolean | false | 紧凑间距 | | feature | boolean | false | Feature 卡片样式 | | featureBg | string | — | Feature 卡片背景图 URL | | inputCard | boolean | false | 带输入/操作底栏的卡片样式 |

子组件

  • VCardBody — 卡片内容区
  • VCardFooter — 卡片底部区
  • VCardImage — 卡片图片区,alt prop 设置图片描述

StatCard 数据卡片

<template>
  <VStatCard value="1,024" label="总用户" />
  <VStatCard value="98%" label="成功率" accent />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | value | string | — | 显示的数值 | | label | string | — | 标签文字 | | accent | boolean | false | 使用强调色(ore-green) |


FeatureCard 特色卡片

<template>
  <VFeatureCard
    title="产品特性"
    description="一段描述文字"
    bg-image="/feature.jpg"
    bg-alt="特性图片"
  />
  <VFeatureCard title="纯文字卡片" description="无背景图" plain />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | — | 标题 | | description | string | — | 描述文字 | | bgImage | string | — | 背景图 URL | | bgAlt | string | '' | 背景图 alt | | plain | boolean | false | 纯文字样式,无背景图 |


Skeleton 骨架屏

<template>
  <VSkeleton variant="text" />
  <VSkeleton variant="title" width="200px" />
  <VSkeleton variant="image" width="100%" height="200px" />
  <VSkeleton variant="circle" width="48px" height="48px" />
  <VSkeletonCard />
</template>

Skeleton Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'text' \| 'title' \| 'image' \| 'circle' \| 'custom' | 'text' | 预设形状 | | width | string \| number | — | 宽度 | | height | string \| number | — | 高度 |

VSkeletonCard

预设的卡片骨架屏,包含图片区 + 标题 + 两行文本。无 props。


Heading 标题

<template>
  <VHeading level="h1">一级标题</VHeading>
  <VHeading level="h2" gradient>渐变标题</VHeading>
  <VHeading level="h3">三级标题</VHeading>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | level | 'h1' \| 'h2' \| 'h3' \| 'h4' | 'h1' | 标题级别 | | gradient | boolean | false | 应用 ore-gradient 文字效果 |


Tag 标签

<template>
  <VTag>默认标签</VTag>
  <VTag variant="accent">强调标签</VTag>
  <VTag variant="danger">危险标签</VTag>
  <VTag variant="muted">弱化标签</VTag>
  <VTag variant="outline">描边标签</VTag>
  <VTag variant="small">小标签</VTag>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'default' \| 'small' \| 'accent' \| 'muted' \| 'danger' \| 'outline' | 'default' | 视觉风格 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 标签内容 |


Badge 徽标

<template>
  <!-- 数字徽标 -->
  <VBadge :count="5">
    <VButton>消息</VButton>
  </VBadge>

  <!-- 超出上限 -->
  <VBadge :count="200" :overflow-count="99">
    <VButton>通知</VButton>
  </VBadge>

  <!-- 红点徽标 -->
  <VBadge variant="dot" danger>
    <VButton>新消息</VButton>
  </VBadge>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'default' \| 'dot' \| 'count' | 'count' | 展示类型 | | count | number | 0 | 数字(仅 variant="count" 时生效) | | overflowCount | number | 99 | 超过此值显示 ${overflowCount}+ | | danger | boolean | false | 危险/警告颜色 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 被包裹的内容 |


Divider 分割线

<template>
  <!-- 基础分割线 -->
  <VDivider />

  <!-- 虚线 -->
  <VDivider dashed />

  <!-- 带文字 -->
  <VDivider>或</VDivider>

  <!-- 文字靠左 -->
  <VDivider label-position="left">分类</VDivider>

  <!-- 垂直分割线 -->
  <span>左</span>
  <VDivider direction="vertical" />
  <span>右</span>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | direction | 'horizontal' \| 'vertical' | 'horizontal' | 方向 | | dashed | boolean | false | 虚线样式 | | labelPosition | 'left' \| 'center' \| 'right' | 'center' | 文字位置 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 分割线文字 |


Container 容器

<template>
  <VContainer>固定宽度容器</VContainer>
  <VContainer fluid>全宽容器</VContainer>
  <VContainer bordered>带边框容器</VContainer>
  <VContainer border-top>仅顶部边框</VContainer>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | fluid | boolean | false | 去除最大宽度限制 | | bordered | boolean | false | 四边边框 | | borderTop | boolean | false | 仅顶部边框 | | borderBottom | boolean | false | 仅底部边框 |


Grid 栅格

<template>
  <VGrid cols="cols-2" gap="md">
    <div>项目 1</div>
    <div>项目 2</div>
  </VGrid>

  <VGrid cols="cols-3" gap="lg" bordered>
    <div>A</div>
    <div>B</div>
    <div>C</div>
  </VGrid>

  <VGrid cols="auto-fit" gap="sm">
    <div>自适应</div>
    <div>自适应</div>
    <div>自适应</div>
  </VGrid>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | cols | 'cols-2' \| 'cols-3' \| 'cols-4' \| 'auto-fit' \| 'aside' | 'cols-3' | 列布局 | | gap | 'none' \| 'sm' \| 'md' \| 'lg' | 'md' | 间距 | | bordered | boolean | false | 单元格边框 |


FloatButton 浮动按钮

<template>
  <!-- 返回顶部 -->
  <VFloatButton back-top />

  <!-- 自定义内容 -->
  <VFloatButton position="bottom-left" @click="handleAction">
    ✏️
  </VFloatButton>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | backTop | boolean | false | 返回顶部模式 | | position | 'bottom-right' \| 'bottom-left' | 'bottom-right' | 固定位置 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | click | (event: MouseEvent) | 点击时触发 |


SocialButton 社交链接按钮

<template>
  <VSocialButton href="https://github.com" target="_blank">
    GitHub
  </VSocialButton>
  <VSocialButton href="https://twitter.com" small>
    Twitter
  </VSocialButton>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | href | string | — | 链接地址 | | target | string | '_blank' | 链接打开方式 | | rel | string | 'noopener noreferrer' | rel 属性 | | small | boolean | false | 紧凑样式 |


Tabs 标签页

<template>
  <VTabs v-model:selected="activeTab">
    <VTabsList>
      <VTab :index="0">标签一</VTab>
      <VTab :index="1">标签二</VTab>
      <VTab :index="2">标签三</VTab>
    </VTabsList>
    <VTabPanel :index="0">内容一</VTabPanel>
    <VTabPanel :index="1">内容二</VTabPanel>
    <VTabPanel :index="2">内容三</VTabPanel>
  </VTabs>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const activeTab = ref(0);
</script>

VTabs Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | id | string | 'tabs' | 容器 ID | | selected | number | 0 | 当前选中索引(支持 v-model:selected) |

VTabs Events

| 事件名 | 参数 | 说明 | |--------|------|------| | update:selected | (index: number) | 选中项变化时触发 |

VTab Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | index | number | — | 标签索引(0-based) |

VTabPanel Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | index | number | — | 面板索引(与对应 Tab 匹配) |


HeroBanner 主视觉横幅

<template>
  <VHeroBanner
    title="Welcome to MSCPO"
    subtitle="现代化组件库"
    label="NEW"
    gradient
  >
    <VButton variant="ore-green">开始使用</VButton>
    <VButton variant="ore-dark">了解更多</VButton>
  </VHeroBanner>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | — | 主标题 | | subtitle | string | — | 副标题 | | label | string | — | 标签文字 | | gradient | boolean | false | 渐变背景 |

Slots

| 插槽名 | 说明 | |--------|------| | default | 操作按钮区 |


Bubble 消息气泡

聊天消息气泡,支持反应和折叠。

<template>
  <VBubble variant="received" align="start" timestamp="10:30">
    你好!
  </VBubble>

  <VBubble variant="sent" align="end" timestamp="10:31" grouped>
    我很好,谢谢
  </VBubble>

  <VBubble
    variant="received"
    :reactions="[{ emoji: '👍', count: 3, active: true }]"
    @react="handleReact"
  >
    收到消息
  </VBubble>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'sent' \| 'received' | 'sent' | 发送/接收 | | align | 'start' \| 'end' | 'end' | 对齐方式 | | grouped | boolean | false | 是否与前一条消息分组 | | reactions | Reaction[] | — | 表情反应列表 | | collapsible | boolean | false | 是否可折叠 | | collapsed | boolean | false | 折叠状态(受控) | | header | string | — | 头部文字 | | footer | string | — | 底部文字 | | timestamp | string | — | 时间戳 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | react | (emoji: string) | 点击表情反应时触发 | | toggleCollapse | — | 折叠状态切换时触发 |

Reaction 类型

interface Reaction {
  emoji: string;
  count: number;
  active?: boolean;
}

Message 消息

完整的聊天气息组件,包含头像、发送者、气泡。

<template>
  <VMessage
    variant="received"
    sender="Alice"
    avatar-src="/alice.jpg"
    timestamp="10:30"
  >
    你好!
  </VMessage>

  <VMessage
    variant="sent"
    sender="Bob"
    avatar-fallback="B"
    timestamp="10:31"
    grouped
  >
    我很好
  </VMessage>

  <VMessage variant="received" footer="已读">
    <template #after>
      <VButton size="sm">回复</VButton>
    </template>
    消息内容
  </VMessage>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'sent' \| 'received' | 'received' | 消息方向 | | avatarSrc | string | — | 头像图片 | | avatarAlt | string | — | 头像 alt | | avatarFallback | string | — | 头像回退文字 | | avatarSize | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | 头像尺寸 | | avatarStatus | 'online' \| 'offline' \| 'away' | — | 头像状态 | | sender | string | — | 发送者名称 | | timestamp | string | — | 时间戳 | | footer | string | — | 气泡底部文字 | | grouped | boolean | false | 是否分组(隐藏头像和发送者) |

Slots

| 插槽名 | 说明 | |--------|------| | default | 消息内容 | | after | 气泡下方的附加内容 |


MessageScroller 消息滚动容器

带自动滚动和加载更多的消息列表容器。

<template>
  <VMessageScroller
    :loading="isLoading"
    :auto-scroll="true"
    :show-scroll-to-bottom="true"
    @load-more="fetchHistory"
  >
    <VMessage v-for="msg in messages" :key="msg.id" v-bind="msg">
      {{ msg.text }}
    </VMessage>
  </VMessageScroller>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const isLoading = ref(false);
const messages = ref([]);
const fetchHistory = () => { isLoading.value = true; /* ... */ };
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | autoScroll | boolean | true | 新内容时自动滚动到底部 | | showScrollToBottom | boolean | true | 向上滚动时显示"回到底部"按钮 | | loading | boolean | false | 是否正在加载历史消息 | | loadMoreThreshold | number | 100 | 距离顶部多少 px 时触发 loadMore |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | loadMore | — | 滚动到顶部阈值时触发 |


Marker 消息标记

聊天中的状态/系统消息标记。

<template>
  <!-- 状态标记 -->
  <VMarker variant="status" color="#10b981">Alice 上线了</VMarker>

  <!-- 系统消息 -->
  <VMarker variant="system">消息已撤回</VMarker>

  <!-- 带时间的分隔线 -->
  <VMarker variant="divider" timestamp="今天 10:30" />

  <!-- 标签 -->
  <VMarker variant="label">新消息</VMarker>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | 'status' \| 'system' \| 'divider' \| 'label' | 'status' | 标记类型 | | color | string | — | 状态圆点颜色 | | timestamp | string | — | 时间戳(divider 变体使用) |

Slots

| 插槽名 | 说明 | |--------|------| | default | 标记文字内容 |


Attachment 附件

文件附件展示,支持上传状态。

<template>
  <VAttachment
    name="report.pdf"
    size="2.4 MB"
    type="PDF"
    state="loaded"
  />

  <VAttachment
    name="image.png"
    type="PNG"
    state="uploading"
    :progress="65"
  />

  <VAttachment
    name="video.mp4"
    state="error"
    @remove="handleRemove"
  />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | name | string | — | 文件名 | | size | string | — | 文件大小,如 "2.4 MB" | | type | string | — | 文件类型,如 "PDF", "PNG" | | thumbnail | string | — | 缩略图 URL | | state | 'idle' \| 'uploading' \| 'error' \| 'loaded' | 'loaded' | 状态 | | progress | number | 0 | 上传进度 0-100 |

Events

| 事件名 | 参数 | 说明 | |--------|------|------| | remove | — | 点击移除按钮时触发 | | click | — | 点击附件时触发 |

Slots

| 插槽名 | 说明 | |--------|------| | actions | 自定义操作按钮 |


样式定制

CSS 变量

所有组件基于 CSS 变量构建,可在 :root 覆盖:

:root {
  /* 字体 */
  --mscpo-font-main: system-ui, -apple-system, sans-serif;
  --mscpo-font-mono: ui-monospace, monospace;

  /* 颜色 */
  --mscpo-color-black: #111111;
  --mscpo-color-white: #ffffff;
  --mscpo-ore-green: #3c8527;
  --mscpo-ore-green-hover: #489e31;
  --mscpo-hero-red: #e60039;
  --mscpo-ore-dark: #1e2a38;

  /* 渐变 */
  --mscpo-ore-gradient: linear-gradient(135deg, #050505 0%, #1e2a38 100%);

  /* 布局 */
  --mscpo-header-height: 64px;
  --mscpo-max-width: 1600px;
  --mscpo-gutter: 20px;

  /* 边框 */
  --mscpo-border-width: 2px;
  --mscpo-border-color: #000000;
  --mscpo-border-radius: 2px;

  /* 动画 */
  --mscpo-ease-swiss: cubic-bezier(0.16, 1, 0.3, 1);
}

自定义主题示例

/* 暗色主题 */
[data-theme="dark"] {
  --mscpo-color-black: #ffffff;
  --mscpo-color-white: #111111;
  --mscpo-ore-dark: #0d1520;
  --mscpo-border-color: #ffffff;
}

响应式断点

$bp-xl: 1200px;
$bp-lg: 1024px;
$bp-md: 768px;

可使用 SCSS mixin:

@use '@mscpore-vue/ui/src/styles/mixins' as *;

.my-component {
  @include respond-below($bp-md) {
    padding: 8px;
  }
}

TypeScript 类型

所有类型定义通过 @mscpore-vue/ui 直接导出:

import type {
  ButtonProps,
  ButtonEmits,
  ButtonVariant,
  InputProps,
  InputEmits,
  DialogProps,
  DialogEmits,
  // ... 其他类型
} from '@mscpore-vue/ui';

开发

# 安装依赖
pnpm install

# 启动开发服务器
pnpm dev

# 构建
pnpm build

# 运行测试
pnpm test

# 运行测试覆盖率
pnpm test:coverage

# 运行性能基准
pnpm test:bench

License

MIT