npm.io
1.0.2 • Published 5d ago

msg-cards-xh

Licence
MIT
Version
1.0.2
Deps
0
Size
200 kB
Vulns
0
Weekly
0

msg-cards · 消息卡片推送组件库

基于 Vue 3 + TypeScript + Vite 的科技风消息卡片组件库,提供异常告警、机房参数展示、数据仓、机房监控全景图、告警数值、地理位置标签等 8 种卡片样式,适用于数据大屏 / 监控看板 / 指挥中心消息推送场景。

所有组件均支持 手动关闭(× 按钮)倒计时自动关闭,并在关闭时触发统一的 @close 事件。


一、环境要求

工具 推荐版本
Node.js >= 16.0,建议 18.x / 20.x
Vue ^3.2.0(已声明为 peerDependency)
包管理器 npm / pnpm / yarn 均可

二、快速接入(三步使用)

1. 安装依赖

在已有 Vue 3 项目中执行:

npm install msg-cards
# 或
pnpm add msg-cards
# 或
yarn add msg-cards
2. 引入样式(重要)

组件的样式(主题色、阴影、切角等)单独打包在 msg-cards/dist/style.css。需在应用入口全局引入一次

// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'

// 必须引入样式文件(只引入一次)
import 'msg-cards/dist/style.css'

createApp(App).mount('#app')
3. 注册组件(任选其一)
方式 A:全局注册(适合整站统一使用)
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import MsgCards from 'msg-cards'
import 'msg-cards/dist/style.css'

createApp(App)
  .use(MsgCards)   // 一次性全局注册 8 个组件
  .mount('#app')

在任意 .vue 模板中直接写标签:

<template>
  <MsgCard28 title="异常告警" :items="alerts" />
  <MsgCard34 label="告警数据" :value="128" />
</template>
方式 B:按需引入(推荐,打包体积最小)
<script setup lang="ts">
import { MsgCard28, MsgCard31, MsgCard34 } from 'msg-cards'
import type { AlertItem } from 'msg-cards'

const alerts: AlertItem[] = [
  { label: '数据中心01', value: '温度正常', level: 'success' },
  { label: '数据中心02', value: '异常', level: 'danger' }
]
</script>

<template>
  <MsgCard28 title="异常告警" :items="alerts" />
  <MsgCard31
    title="机房参数展示"
    :items="[
      { label: 'CPU', value: '62%', ratio: 0.62 },
      { label: '内存', value: '48%', ratio: 0.48 },
      { label: '磁盘', value: '81%', ratio: 0.81 }
    ]"
  />
  <MsgCard34 label="今日告警" :value="128" />
</template>

三、通用 Props / Events(所有组件均支持)

属性 / 事件 类型 默认值 说明
duration number 0 倒计时秒数;> 0 自动关闭,0 只能手动点 × 关闭
@close Event 关闭触发(倒计时归零、点 × 或点蒙层均触发)
overlay boolean true 是否显示深色蒙层
centered boolean true 是否在屏幕居中(需 overlay=true;设为 false 则卡片保持原有页面流式定位)
position 'top' | 'center' | 'bottom' 'center' 居中时垂直对齐位置(仅 centered=true 时生效)
overlayClosable boolean true 点击蒙层是否关闭卡片
overlayOpacity number 0.6 蒙层透明度(0-1)
pulse boolean true 是否开启警报闪烁动效;关闭后卡片使用正常静态样式

使用示例:

<template>
  <!-- 居中蒙层(默认),点击蒙层或倒计时结束关闭 -->
  <MsgCard28 title="告警" :items="items" :duration="5" @close="onClosed" />

  <!-- 顶部弹出,居中显示 -->
  <MsgCard31 title="参数展示" :position="'top'" :overlay-opacity="0.4" :duration="8" @close="onClosed" />

  <!-- 无蒙层,保持原有页面布局(用于页面内嵌入) -->
  <MsgCard33 title="数据中心" :overlay="false" :centered="false" />

  <!-- 底部弹出,不允许点击蒙层关闭 -->
  <MsgCard34 label="告警数据" :value="128" :position="'bottom'" :overlay-closable="false" />
</template>

关闭按钮(×)位于卡片标题栏右上角,hover 高亮;倒计时数字显示在关闭按钮左侧(仅 duration > 0 时出现)。蒙层点击关闭时同样触发 @close 事件。


四、在 TS 文件中命令式调用(不依赖 Vue 模板)

当你在 .ts / .tsx 工具模块(例如数据推送服务、全局通知中心、事件处理函数)中,希望直接「发一条卡片消息」,可使用 msg-cards 提供的命令式 API:

// src/services/message-push.ts
import { pushCard28, pushCard34 } from 'msg-cards'
import 'msg-cards/dist/style.css'

// 方式 1:使用类型化快捷接口(推荐)
const card = pushCard28(
  {
    title: '异常告警',
    duration: 8,
    items: [
      { label: '数据中心01', value: '温度正常', level: 'success' },
      { label: '数据中心02', value: '异常', level: 'danger' }
    ]
  },
  { zIndex: 9999 }
)

// 返回值提供 close() 方法,可手动提前关闭
setTimeout(() => card.close(), 2000)
// 方式 2:通用 pushCard,手动传入任意组件
import { h } from 'vue'
import { pushCard, MsgCard31 } from 'msg-cards'

const card = pushCard(
  MsgCard31,
  {
    tagLabel: '告警',
    title: '数据中心01机房参数展示',
    items: [
      { label: 'CPU', value: '62%', ratio: 0.62 },
      { label: '内存', value: '48%', ratio: 0.48 }
    ],
    duration: 10,
    onClose: () => console.log('卡片已关闭')
  }
)
// 方式 3:自定义容器(例如把卡片推到自己的 DOM 容器里,而不是 body 浮层)
import { pushCard32 } from 'msg-cards'

pushCard32(
  { title: '机房监控全景图' },
  { container: '#dashboard-cards', insertMode: 'prepend' }
)
命令式 API 参考

所有 pushCardNN(...) 都接受 Props + PushOptions,返回 PushResult

// 类型定义
import type {
  PushResult, PushOptions,
  Push28Props, Push29Props /* ... */
} from 'msg-cards'

interface PushOptions {
  container?: Element | string        // 自定义容器,默认创建独立浮层
  insertMode?: 'append' | 'prepend' // 插入方式
  zIndex?: number                    // 浮层 z-index,默认 9999
  /** 是否显示蒙层,默认为 true */
  overlay?: boolean
  /** 是否居中,默认为 true */
  centered?: boolean
  /** 居中时垂直位置,默认为 'center' */
  position?: 'top' | 'center' | 'bottom'
  /** 点击蒙层是否关闭,默认为 true */
  overlayClosable?: boolean
  /** 蒙层透明度,0-1,默认为 0.6 */
  overlayOpacity?: number
  /** 是否开启警报闪烁动效,默认为 true */
  pulse?: boolean
}

interface PushResult {
  close: () => void    // 手动销毁卡片
  vnode: VNode         // 底层 VNode 引用(高级用法)
  el: HTMLElement       // 实际挂载的 DOM 容器
}
在事件流中的典型用法
// src/composables/usePushNotification.ts
import { ref } from 'vue'
import { pushCard28, pushCard34 } from 'msg-cards'

const list = ref<{ close: () => void }[]>([])

export function notifyError(title: string, items: Array<{ label: string; value: string; level?: string }>) {
  const card = pushCard28({
    title,
    items,
    duration: 10,
    // 顶部弹出蒙层
    position: 'top',
    overlayOpacity: 0.5
  })
  list.value.push(card)
}

export function notifyBigNumber(label: string, value: number) {
  // 无蒙层,直接嵌入页面流中
  pushCard34({
    label,
    value,
    overlay: false,
    centered: false
  })
}

export function closeAll() {
  list.value.forEach(c => c.close())
  list.value = []
}
TSX / render 函数中的用法
// src/components/Dashboard.tsx 中的 render 函数用法
import { defineComponent } from 'vue'
import { MsgCard28 } from 'msg-cards'

export default defineComponent({
  setup() {
    return () => (
      <MsgCard28
        title="异常告警"
        duration={8}
        items={[
          { label: '数据中心01', value: '温度正常', level: 'success' }
        ]}
        onClose={() => console.log('closed')}
      />
    )
  }
})

**提示:TSX 用法本质上仍是模板声明式用法;pushCard*() 是真正的“命令式推送”。前者用于 `.ts/.tsx 文件中主动触发卡片推送。


五、各组件 Props 速览

MsgCard28 · 异常告警列表
Prop 类型 默认值 说明
title string '异常告警' 标题
items AlertItem[] [] 告警条目列表
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效
interface AlertItem {
  label: string
  value: string | number
  level?: 'info' | 'success' | 'warning' | 'danger'
}

MsgCard29 · 数据中心异常告警(含场景图)
Prop 类型 默认值 说明
title string '数据中心异常告警' 标题
subtitle string '数据中心C01机房' 场景图下方文字
time string '' 右侧显示的时间戳
params RoomParam[] [] 参数列表
sceneImage string '' 自定义场景图 URL,未传时使用内置 SVG
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效
interface RoomParam {
  label: string
  value: string | number
  unit?: string
}

MsgCard30 · 数据仓对比
Prop 类型 默认值 说明
title string '三号仓' 标题
icon string '🏠' 图标字符
rows WarehouseRow[] [] 数据行
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效
interface WarehouseRow {
  label: string
  today: number | string
  yesterday: number | string
  trend?: 'up' | 'down' | 'flat'
  trendValue?: string | number
}

MsgCard31 · 机房参数环形图
Prop 类型 默认值 说明
tagLabel string '告警' 顶部角标文字
title string '数据中心01机房参数展示' 标题
items MetricItem[] [] 环形指标项
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效
interface MetricItem {
  label: string
  value: number | string
  ratio?: number  // 0 - 1,决定环形进度
}

MsgCard32 · 机房监控全景图
Prop 类型 默认值 说明
title string '机房监控全景图' 标题
items MonitorItem[] [] 机房场景列表
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效
interface MonitorItem {
  title: string
  subtitle?: string
  image?: string   // 不传时使用内置 SVG 场景图
}

MsgCard33 · 数据中心网格
Prop 类型 默认值 说明
title string '数据中心01机房' 标题
rows Cell[][] [] 二维数组,按行 × 列排列
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效
interface Cell {
  label: string
  value: string | number
}

MsgCard34 · 告警大数值
Prop 类型 默认值 说明
icon string '!' 左侧圆形图标内容
label string '告警数据' 标题
value string | number 236.452 大数值
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效

MsgCard35 · 地理位置标签
Prop 类型 默认值 说明
label string '北京' 旗帜中央文字
duration number 0 自动关闭秒数
overlay boolean true 是否显示蒙层
centered boolean true 是否居中
position 'top' | 'center' | 'bottom' 'center' 垂直位置
overlayClosable boolean true 点击蒙层关闭
overlayOpacity number 0.6 蒙层透明度
pulse boolean true 是否开启警报闪烁动效

所有类型定义一键引入
import type {
  AlertLevel,
  AlertItem,
  RoomParam,
  WarehouseRow,
  MonitorItem
} from 'msg-cards'

六、从本仓库构建发布(作为依赖包提供者的流程)

1. 克隆与安装
git clone <仓库地>
cd msg-cards
npm install
2. 本地预览全部卡片
npm run dev
# 打开 http://localhost:5173

访问后可在浏览器中看到 8 种卡片的完整效果,以及带倒计时 / 手动关闭的交互演示。

3. 构建库产物(ES + UMD + 类型声明)
npm run build          # 等价于 npm run build:lib

构建完成后 dist/ 目录:

dist/
├── msg-cards.es.js        # ESM 产物(现代打包工具使用)
├── msg-cards.umd.js       # UMD 产物(<script> 标签 / require 使用)
├── style.css              # 统一主题样式(必须引入一次)
└── types/
    ├── index.d.ts
    ├── components/MsgCard28.vue.d.ts
    ├── …
    └── types/index.d.ts   # AlertItem / RoomParam 等类型

构建配置文件:vite.lib.config.ts

# 在 msg-cards 目录
npm run build
npm link                 # 将 msg-cards 链接到全局 node_modules

# 在你的项目目录
npm link msg-cards       # 将本地构建包以软链方式引入
5. 发布到 npm / 私有仓库
npm run build            # 先构建
npm login                # 登录到对应仓库
npm publish              # 仅会发布 dist/(由 package.json files 字段控制)

若发布到公司私有仓库(例如 Verdaccio / GitLab Registry),可在 .npmrc 中配置 registry 或通过 --registry 参数指定。

6. 仅做类型检查(不构建)
npm run type-check       # 等同于 vue-tsc --noEmit

七、UMD 浏览器直接引入(无需构建工具)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>msg-cards UMD Demo</title>
  <link rel="stylesheet" href="./dist/style.css" />
</head>
<body>
  <div id="app">
    <msg-card28 :title="'异常告警'" :items="items" :duration="10" @close="() => console.log('closed')" />
    <msg-card34 :label="'告警数据'" :value="128" />
  </div>

  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <script src="./dist/msg-cards.umd.js"></script>
  <script>
    const { createApp, ref } = Vue
    const { MsgCard28, MsgCard34 } = window.MsgCards

    createApp({
      components: { MsgCard28, MsgCard34 },
      setup() {
        return {
          items: ref([
            { label: '数据中心01', value: '温度正常', level: 'success' },
            { label: '数据中心02', value: '异常', level: 'danger' }
          ])
        }
      }
    }).mount('#app')
  </script>
</body>
</html>

八、主题色自定义

主题色(深红 #ff2a44)定义在 CSS 变量中,可在项目全局覆盖:

/* src/styles/msg-cards-override.css */
:root {
  --mc-primary: #00c2ff;           /* 主色改为青色 */
  --mc-primary-light: #3ddcff;
  --mc-primary-dark: #0077a8;
  --mc-primary-glow: rgba(0, 194, 255, 0.45);
  --mc-panel-border: rgba(0, 194, 255, 0.55);
}

在入口文件中紧随 msg-cards/dist/style.css 之后引入即可:

import 'msg-cards/dist/style.css'
import './styles/msg-cards-override.css'

九、目录结构

msg-cards/
├── src/
│   ├── components/         # 8 个卡片组件(均支持 duration/close)
│   │   ├── MsgCard28.vue ~ MsgCard35.vue
│   │
│   ├── styles/theme.css    # 主题色 + 基础样式
│   ├── types/index.ts      # AlertItem / RoomParam / WarehouseRow / MonitorItem
│   ├── push.ts             # 命令式 API(pushCard28/pushCard29/...)
│   ├── index.ts            # 插件入口,具名导出 + Vue Plugin 导出
│   └── shims-vue.d.ts
│
├── demo/                   # 本地开发示例(App.vue / main.ts)
├── index.html              # Vite 开发入口
├── vite.config.ts          # 开发 / Demo 构建配置
├── vite.lib.config.ts      # 库模式构建配置(生产发布用)
├── tsconfig.json           # 开发用 tsconfig(包含 demo)
├── tsconfig.lib.json       # 库模式专用 tsconfig(仅 src)
└── package.json

十、常见问题

Q1. 引入后卡片没有显示样式 / 颜色 / 切角?

确认已在全局入口执行一次 import 'msg-cards/dist/style.css'。若用按需引入(未调用 use(MsgCards)),样式仍需手动引入。

Q2. 卡片显得太宽 / 太窄,不贴合我的大屏?

卡片组件均采用内容自适应宽度(内部 width: 420px ~ 520px 等仅为默认),可通过外层容器设置 width / transform: scale() 或使用 CSS Grid 排列多个卡片。

Q3. TypeScript 报错找不到 .vue 类型?

确保宿主项目 tsconfig.jsoncompilerOptions.types 包含 "vite/client"(或已有 shims-vue.d.ts)。从包中引入时,类型定义已输出到 msg-cards/dist/types/

Q4. 想覆盖某张卡片的内部颜色、阴影等细节?

由于每个组件的 <style scoped> 使用了 --mc-* 变量,直接在宿主项目覆盖同名 CSS 变量即可全局生效;也可对特定组件外层 :deep() 覆盖。

Q5. npm run buildSearch string not found: supportedTSExtensions

旧的 vue-tsc 1.8.x 与 TypeScript 5.5+ 不兼容。本仓库已锁定 typescript ~5.4.5 + vue-tsc ^2.0.0,重新 npm install 即可。

Q6. 如何只启用手动关闭,禁用倒计时自动关闭?

不传入 duration 或传 :duration="0" 即可。此时卡片右上角仍显示 × 按钮,点击后触发 @close

Q7. 倒计时结束或点击关闭后,如何让同一卡片重新显示?

当前关闭会从 DOM 移除。需要通过父组件用 v-if 重新挂载:

<template>
  <MsgCard28 v-if="show" :duration="10" @close="show = false" :items="items" />
  <button @click="show = true">重新推送</button>
</template>

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

十一、版本与 License

  • 版本:1.0.0(代码中通过 import { version } from 'msg-cards' 可读取)
  • License:MIT

Keywords