Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mscpore-vue3

License: MIT Vue.js TypeScript Turborepo pnpm

基于 MSCPO 像素网格设计语言的 Vue 3 组件库。提供完整的 TypeScript 类型支持,所有组件遵循严格的方形边角、2px 黑边、系统字体的设计约束。

✨ 特性

  • 🟩 Vue 3.5+ — 基于最新 Vue 3 组合式 API,<script setup> 语法
  • 🔷 TypeScript — 完整的类型声明(*.types.ts),导出所有 Props / Emits 接口
  • 🎨 MSCPO 设计语言 — 2px 黑色实线边框、方形边角、ore-dark / ore-green / ore-purple 主题色
  • 📦 Tree-shaking — 支持按需导入,未使用的组件不会打入最终包
  • ⚡ tsdown 构建 — 基于 Rolldown,同时输出 CJS + ESM + DTS
  • 🛝 Playground — 基于 antdv-next 的实时组件演示环境,支持 HMR
  • ✅ 测试就绪 — Vitest + jsdom / happy-dom 单元测试基础设施

📦 安装

# pnpm
pnpm add mscpore-vue3

# npm
npm install mscpore-vue3

# yarn
yarn add mscpore-vue3

依赖

依赖 版本 说明
vue ≥ 3.3 框架依赖

🚀 快速开始

<template>
  <VContainer>
    <VHeading level="h1" gradient>
      Welcome to MSCPO
    </VHeading>

    <VGrid cols="cols-3" gap="md">
      <VCard hoverable v-for="i in 3" :key="i">
        <VCardImage>
          <img :src="`https://picsum.photos/360/200?${i}`" alt="demo" />
        </VCardImage>
        <VCardBody>
          <VBadge :count="5">
            <VHeading level="h3">Card {{ i }}</VHeading>
          </VBadge>
          <p style="font-size:0.85rem;color:#666">MSCPO pixel-grid card.</p>
        </VCardBody>
      </VCard>
    </VGrid>

    <VButton variant="ore-green" @click="handleClick" style="margin-top:16px">
      Get Started
    </VButton>
  </VContainer>
</template>

<script setup lang="ts">
import {
  VBadge, VButton, VCard, VCardBody, VCardImage,
  VContainer, VGrid, VHeading,
} from 'mscpore-vue3';

const handleClick = () => console.log('clicked');
</script>

全局安装

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import MscporeUI from 'mscpore-vue3';
import 'mscpore-vue3/style.css';

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

全局安装后所有 V* 组件自动注册,无需单独引入。


📁 项目结构

packages/ui/src/
├── components/
│   ├── Alert/           # 提示
│   ├── Attachment/      # 附件
│   ├── Avatar/          # 头像 + 头像组
│   ├── Badge/           # 徽标
│   ├── Bubble/          # 聊天气泡
│   ├── Button/          # 按钮
│   ├── Card/            # 卡片 + CardBody + CardFooter + CardImage
│   ├── Container/       # 容器
│   ├── Dialog/          # 对话框
│   ├── Divider/         # 分割线
│   ├── Empty/           # 空状态
│   ├── ErrorBoundary/   # 错误边界
│   ├── FeatureCard/     # 特色卡片
│   ├── FloatButton/     # 浮动按钮
│   ├── Grid/            # 网格
│   ├── Heading/         # 标题
│   ├── HeroBanner/      # 主横幅
│   ├── Input/           # 输入框
│   ├── Marker/          # 会话标记
│   ├── Message/         # 消息
│   ├── MessageScroller/ # 消息滚动容器
│   ├── Progress/        # 进度条
│   ├── SearchInput/     # 搜索框
│   ├── Skeleton/        # 骨架屏
│   ├── SocialButton/    # 社交按钮
│   ├── StatCard/        # 统计卡片
│   ├── Tabs/            # 标签页
│   ├── Tag/             # 标签
│   └── Tooltip/         # 工具提示
├── styles/
│   ├── _variables.scss  # MSCPO 设计令牌
│   ├── _mixins.scss     # 可复用样式混入
│   └── _index.scss      # 统一入口(@forward)
├── _utils/
│   └── with-install.ts  # 组件 install 注册工具
└── index.ts

API 参考

所有组件名称以 V 为前缀(如 VButton、VCard)。Props 接口以组件名 + Props 命名导出。 本章节收录 29 个组件的完整 API,按功能分组。

Button 按钮

import { VButton } from 'mscpore-vue3';

Props

属性 类型 默认值 说明
variant 'ore-dark' | 'ore-green' | 'ore-purple' 'ore-dark' 视觉变体
fullWidth boolean false 撑满容器宽度
disabled boolean false 禁用状态

Emits

事件 载荷 说明
click MouseEvent 点击事件

用例

<VButton variant="ore-dark">Dark</VButton>
<VButton variant="ore-green">Green CTA</VButton>
<VButton variant="ore-purple">AI Search</VButton>
<VButton variant="ore-dark" full-width>Full Width</VButton>
<VButton variant="ore-green" disabled>Disabled</VButton>

Input 输入框

import { VInput } from 'mscpore-vue3';

Props

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

Slots

名称 说明
prefix 前缀
suffix 后缀

用例

<VInput v-model="text" placeholder="Type..." />
<VInput v-model="text" error placeholder="Error" />
<VInput v-model="text">
  <template #prefix>🔍</template>
  <template #suffix>.com</template>
</VInput>

SearchInput 搜索框

import { VSearchInput } from 'mscpore-vue3';
属性 类型 默认值 说明
modelValue string '' 搜索值 (v-model)
placeholder string '搜索...' 占位文本

Slots: icon – 搜索图标

<VSearchInput v-model="q" placeholder="搜索..." style="max-width:360px">
  <template #icon>🔍</template>
</VSearchInput>

Dialog 对话框

import { VDialog } from 'mscpore-vue3';
属性 类型 默认值 说明
open boolean false 显示/隐藏 (v-model)
title string — 标题
closable boolean true 关闭按钮+遮罩关闭
width string | number 440 宽度

Slots: default, footer

<VDialog v-model:open="show" title="CONFIRM">
  <p>确定执行此操作?</p>
  <template #footer>
    <VButton variant="ore-dark" @click="show=false">取消</VButton>
    <VButton variant="ore-green" @click="confirm">确认</VButton>
  </template>
</VDialog>

Tabs 标签页

import { VTabs, VTabsList, VTab, VTabPanel } from 'mscpore-vue3';

VTabs: selected (v-model), id | VTab: index | VTabPanel: index

<script setup>const tab = ref(0);</script>
<VTabs v-model:selected="tab">
  <VTabsList>
    <VTab :index="0">First</VTab>
    <VTab :index="1">Second</VTab>
  </VTabsList>
  <VTabPanel :index="0">Content 1</VTabPanel>
  <VTabPanel :index="1">Content 2</VTabPanel>
</VTabs>

Container 容器

fluid bordered borderTop borderBottom (均为 boolean)

<VContainer><p>居中</p></VContainer>
<VContainer fluid><p>全宽</p></VContainer>
<VContainer bordered border-top><p>带边框</p></VContainer>

Heading 标题

level ('h1'|'h2'|'h3'|'h4', 默认 'h1'), gradient (boolean)

<VHeading level="h1" gradient>Hero</VHeading>
<VHeading level="h2">Section</VHeading>
<VHeading level="h3">Card</VHeading>

Tag 标签

variant: 'default'|'small'|'accent'|'muted'|'danger'|'outline' (默认 'default')

<VTag>Default</VTag>
<VTag variant="accent">New</VTag>
<VTag variant="danger">Error</VTag>
<VTag variant="outline">Draft</VTag>

Badge 徽标

variant ('default'|'dot'|'count'), count, overflowCount, danger

<VBadge :count="5"><VButton>Messages</VButton></VBadge>
<VBadge variant="dot" danger />

Card 卡片

VCard: hoverable compact feature featureBg inputCard 子组件: VCardImage, VCardBody, VCardFooter

<VCard hoverable>
  <VCardImage><img src="/img.jpg" /></VCardImage>
  <VCardBody><VHeading level="h3">Title</VHeading></VCardBody>
  <VCardFooter><VButton variant="ore-green">Action</VButton></VCardFooter>
</VCard>
<VCard feature feature-bg="/bg.jpg"><VCardBody>Hover reveal</VCardBody></VCard>

StatCard 统计卡片

value (string), label (string), accent (boolean)

<VStatCard value="100+" label="Projects" accent />

FeatureCard 特色卡片

title description bgImage bgAlt plain

<VFeatureCard title="AI" description="Powered by ML" bg-image="/ai.jpg" />
<VFeatureCard title="Free" description="Open source" plain />

Grid 网格

cols ('cols-2'|'cols-3'|'cols-4'|'auto-fit'|'aside'), gap ('none'|'sm'|'md'|'lg'), bordered

<VGrid cols="cols-3" gap="md">
  <VCard v-for="i in 6" :key="i"><VCardBody>Item {{ i }}</VCardBody></VCard>
</VGrid>

Divider 分割线

direction ('horizontal'|'vertical'), dashed, labelPosition

<VDivider />
<VDivider>OR</VDivider>
<VDivider direction="vertical" />

Avatar 头像

VAvatar: src alt fallback size ('sm'|'md'|'lg'|'xl') status ('online'|'offline'|'away') statusColor VAvatarGroup: 无特殊 props

<VAvatar src="/a.jpg" size="md" status="online" />
<VAvatar fallback="JD" size="lg" />
<VAvatarGroup>
  <VAvatar src="/a.jpg" size="md" />
  <VAvatar fallback="+3" size="md" />
</VAvatarGroup>

Skeleton 骨架屏

variant ('text'|'title'|'image'|'circle'|'custom'), width, height VSkeletonCard: 预构建的卡片骨架

<VSkeleton variant="image" />
<VSkeleton variant="title" />
<VSkeletonCard style="max-width:300px" />

Alert 提示

type ('info'|'success'|'warning'|'error'), title, closable | Emits: close

<VAlert>Info message</VAlert>
<VAlert type="success" title="OK">Done</VAlert>
<VAlert type="error" closable @close="handleClose">Error</VAlert>

Progress 进度条

percent (number, 0-100), status ('normal'|'success'|'error'), showInfo

<VProgress :percent="60" />
<VProgress :percent="100" status="success" />

Empty 空状态

description, icon | Slot: default (action area)

<VEmpty description="No results">
  <VButton variant="ore-green">Create</VButton>
</VEmpty>

Tooltip 工具提示

label (string), placement ('top'|'bottom'|'left'|'right')

<VTooltip label="TOP"><VButton>Hover</VButton></VTooltip>

Bubble 聊天气泡

variant ('sent'|'received'), align, grouped, reactions, collapsible, collapsed, header, footer, timestamp

<VBubble variant="received" timestamp="10:30">Hello!</VBubble>
<VBubble variant="sent">Hi!</VBubble>

Message 消息

组合 Avatar + Bubble。variant avatarSrc avatarAlt avatarFallback avatarSize avatarStatus sender timestamp footer grouped

<VMessage variant="received" sender="ALICE" avatar-src="/a.jpg" timestamp="11:00">
  Hello!
</VMessage>

MessageScroller 消息滚动容器

autoScroll showScrollToBottom loading loadMoreThreshold | Emits: loadMore

<VMessageScroller style="height:400px" @load-more="loadHistory">
  <VMessage v-for="m in msgs" v-bind="m">{{ m.text }}</VMessage>
</VMessageScroller>

Marker 会话标记

variant ('status'|'system'|'divider'|'label'), color, timestamp

<VMarker variant="status">Online</VMarker>
<VMarker variant="divider" timestamp="YESTERDAY" />

Attachment 附件

name size type thumbnail state ('idle'|'uploading'|'error'|'loaded') progress | Emits: remove click

<VAttachment name="report.pdf" size="2.4 MB" type="PDF" @remove="remove" />
<VAttachment name="file.zip" state="uploading" :progress="65" />

FloatButton 浮动按钮

backTop (boolean), position ('bottom-right'|'bottom-left') | Emits: click

<VFloatButton back-top />
<VFloatButton @click="scroll">+</VFloatButton>

SocialButton 社交按钮

href small target rel

<VSocialButton href="https://github.com">GitHub</VSocialButton>

HeroBanner 主横幅

title subtitle label gradient

<VHeroBanner title="BUILD BETTER" subtitle="MSCPO library for Vue 3" label="NEW" gradient>
  <VButton variant="ore-green">START</VButton>
</VHeroBanner>

ErrorBoundary 错误边界

使用 onErrorCaptured 捕获错误,显示降级 UI。无特殊 props。

<VErrorBoundary><RiskyComponent /></VErrorBoundary>

🧰 开发命令

pnpm dev          # 启动开发环境
pnpm dev:play     # 启动 Playground
pnpm build        # 构建所有包
pnpm build:ui     # 仅构建 UI 包
pnpm test         # 运行测试
pnpm lint:all     # 代码检查
pnpm clean        # 清理
pnpm generate:component  # 生成新组件
pnpm rename-pkg   # 替换包名

❓ FAQ

组件名前缀为什么是 V?

遵循项目 COMPONENT_GUIDE.md 约定,所有 UI 组件以 V 为前缀,避免与原生 HTML 元素冲突。

如何按需导入?

import { VButton, VCard } from 'mscpore-vue3';

Tree-shaking 自动排除未使用的代码。

CSS 变量从哪里来?

MSCPO 设计令牌定义在 src/styles/_variables.scss 中,编译为 :root CSS 自定义属性 (--mscpo-*)。引入 style.css 即可。

🤝 贡献

欢迎提交 Issue 和 PR。Fork → 分支 → 提交 → Push → Pull Request。

📄 License

MIT

Releases

Packages

Contributors

Languages