@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/uiPeer 依赖: 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— 卡片图片区,altprop 设置图片描述
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:benchLicense
MIT
