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

qinglin-ui

v1.0.0

Published

QingLin UI 是由青林中医科技开发的企业级 Vue3 组件库

Readme

QingLin UI - Vue 3 企业级 UI 组件库

基于 Vue 3 + Tailwind CSS 的可扩展后台管理 UI 框架,专为企业内部系统设计。

特性

  • 43 个组件 — Button、Input、Select、Table、Pagination、Checkbox、RadioGroup、Modal、Drawer、Tooltip、Tag、Alert、Spin、Empty、Avatar、ConfirmDialog、StatCard 等
  • TypeScript — 完整类型支持,组件均有 .d.ts 定义
  • 完整布局系统 — MainLayout、Header、Sidebar(可折叠、支持多级菜单)
  • 设计系统 — CSS 变量驱动,支持 5 套主题色
  • 组合式函数 — usePagination、useForm、usePermission、useUser 等
  • 工具层 — 权限指令、树形工具
  • 颗粒化 — 每个组件独立引入,支持 tree-shaking
  • 可扩展 — 所有组件基于 Tailwind CSS,易于定制

安装

npm install qinglin-ui

快速开始

全量引入

import { createApp } from 'vue'
import QingLinUI from 'qinglin-ui'
import 'qinglin-ui/style.css'
import App from './App.vue'

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

按需引入

<script setup>
import { QLButton, QLInput } from 'qinglin-ui'
</script>

<template>
  <QLButton variant="primary">按钮</QLButton>
  <QLInput placeholder="请输入" />
</template>

TypeScript 支持

组件使用 TypeScript 编写,提供完整类型提示。各组件的类型定义和使用示例位于 src/components/[ComponentName]/index.ts 文件中。

import { QLButton, QLInput, QLSelect} from 'qinglin-ui'
import type { ButtonProps, InputProps, SelectProps } from 'qinglin-ui'

组件文档

QLButton 按钮

按钮组件,支持 7 种变体和 3 种尺寸。

<template>
  <!-- 基础用法 -->
  <QLButton variant="primary">主要按钮</QLButton>
  <QLButton variant="secondary">次要按钮</QLButton>
  <QLButton variant="outline">轮廓按钮</QLButton>
  <QLButton variant="ghost">幽灵按钮</QLButton>
  <QLButton variant="danger">危险按钮</QLButton>
  <QLButton variant="neutral">中性按钮</QLButton>
  <QLButton variant="text">文字按钮</QLButton>

  <!-- 尺寸 -->
  <QLButton size="sm">小</QLButton>
  <QLButton size="md">中</QLButton>
  <QLButton size="lg">大</QLButton>

  <!-- 加载状态 -->
  <QLButton :loading="true">加载中</QLButton>

  <!-- 禁用 -->
  <QLButton disabled>禁用</QLButton>

  <!-- 块级按钮 -->
  <QLButton block>撑满容器</QLButton>

  <!-- 带图标 -->
  <QLButton :icon="Plus">添加</QLButton>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | variant | String | primary | 按钮样式:primary(主要按钮)/ secondary(次要按钮)/ outline(轮廓按钮)/ ghost(幽灵按钮)/ danger(危险按钮)/ neutral(中性按钮)/ text(文字按钮) | | size | String | md | 按钮尺寸:sm(小)/ md(中)/ lg(大) | | block | Boolean | false | 是否撑满父容器宽度 | | loading | Boolean | false | 加载状态,显示加载指示器 | | disabled | Boolean | false | 禁用状态,禁用点击和交互 | | icon | Object / Function / String | - | 图标组件,支持 lucide-vue-next 图标 | | type | String | button | 原生 button type 属性:button(普通按钮)/ submit(提交按钮)/ reset(重置按钮) |

Events

| 事件名 | 说明 | 参数 | |--------|------|------| | click | 点击事件 | event: MouseEvent |


QLInput 输入框

输入框组件,支持文本、密码、文本域等类型。

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

  <!-- 带标签 -->
  <QLInput v-model="value" label="用户名" placeholder="请输入用户名" required />

  <!-- 密码输入框 -->
  <QLInput v-model="pwd" type="password" label="密码" placeholder="请输入密码" />

  <!-- 文本域 -->
  <QLInput
    v-model="desc"
    type="textarea"
    label="描述"
    placeholder="请输入描述"
    :rows="4"
    :maxlength="200"
    show-count
  />

  <!-- 可清空 -->
  <QLInput v-model="value" allow-clear placeholder="可清空" />

  <!-- 错误状态 -->
  <QLInput v-model="value" error="请输入有效内容" />

  <!-- 禁用 -->
  <QLInput v-model="value" disabled />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | String / Number | '' | 绑定值,支持 v-model | | type | String | text | 输入框类型:text(文本)/ password(密码)/ number(数字)/ email(邮箱)/ textarea(多行文本) | | label | String | - | 标签文本,显示在输入框上方 | | placeholder | String | - | 占位提示文本 | | required | Boolean | false | 必填标记,显示红色星号 | | error | String | - | 错误提示文本,显示在输入框下方 | | size | String | md | 尺寸大小:sm(小)/ md(中)/ lg(大) | | disabled | Boolean | false | 禁用状态,禁用输入和交互 | | readonly | Boolean | false | 只读状态,仅可查看不可编辑 | | allowClear | Boolean | false | 显示清除按钮,点击可清空输入 | | maxlength | Number | - | 最大输入字符数限制 | | showCount | Boolean | false | 显示当前输入字符数统计 | | rows | Number | 4 | textarea 行数,仅在 type="textarea" 时生效 | | resizeable | Boolean | false | 文本域是否可拖拽调整高度,仅 type="textarea" 时生效 |

Events

| 事件名 | 说明 | 参数 | |--------|------|------| | update:modelValue | 值变化 | value: String / Number | | change | 值变化 | value: String / Number | | blur | 失焦事件 | event: FocusEvent | | focus | 聚焦事件 | event: FocusEvent |


QLSelect 选择器

下拉选择器,支持单选、多选、搜索。

<template>
  <!-- 单选 -->
  <QLSelect
    v-model="selected"
    :options="options"
    label="选择"
    placeholder="请选择"
    searchable
    clearable
  />

  <!-- 多选 -->
  <QLSelect
    v-model="multipleSelected"
    :options="options"
    label="多选"
    multiple
    searchable
  />
</template>

<script setup>
import { ref } from 'vue'

const selected = ref(undefined)
const multipleSelected = ref([])

const options = [
  { label: '选项一', value: 1 },
  { label: '选项二', value: 2 },
  { label: '选项三', value: 3 }
]
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | String / Number / Array | - | 绑定值,单选时为 String/Number,多选时为 Array,支持 v-model | | options | Array | [] | 选项列表,格式为 [{ label: string, value: string/number, disabled?: boolean }] | | label | String | - | 标签文本,显示在选择器上方 | | placeholder | String | 请选择 | 占位提示文本 | | required | Boolean | false | 必填标记,显示红色星号 | | disabled | Boolean | false | 禁用状态,禁用选择和交互 | | error | String | - | 错误提示文本,显示在选择器下方 | | size | String | md | 尺寸大小:sm(小)/ md(中)/ lg(大) | | searchable | Boolean | false | 是否可搜索,输入关键字过滤选项 | | clearable | Boolean | false | 是否显示清空按钮,点击可清空已选 | | multiple | Boolean | false | 多选模式,modelValue 应为数组 |

Events

| 事件名 | 说明 | 参数 | |--------|------|------| | update:modelValue | 值变化 | value: String / Number / Array | | change | 值变化 | value: String / Number / Array |


QLTable 表格

数据表格组件,支持自定义列、插槽。

<template>
  <QLTable
    :columns="columns"
    :data="tableData"
    row-key="id"
    :loading="loading"
    @row-click="handleRowClick"
  >
    <!-- 自定义单元格 -->
    <template #cell-status="{ row }">
      <Tag :color="row.status === 'active' ? 'success' : 'danger'">
        {{ row.status === 'active' ? '启用' : '禁用' }}
      </Tag>
    </template>

    <!-- 自定义操作列 -->
    <template #cell-actions="{ row }">
      <QLButton size="sm" variant="text" @click="handleEdit(row)">编辑</QLButton>
      <QLButton size="sm" variant="text" @click="handleDelete(row)">删除</QLButton>
    </template>
  </QLTable>
</template>

<script setup>
const columns = [
  { key: 'name', dataIndex: 'name', title: '名称' },
  { key: 'age', dataIndex: 'age', title: '年龄', align: 'center' },
  { key: 'status', dataIndex: 'status', title: '状态' },
  { key: 'actions', title: '操作', width: '150px' }
]

const tableData = [
  { id: 1, name: '张三', age: 28, status: 'active' },
  { id: 2, name: '李四', age: 32, status: 'inactive' }
]
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | columns | Array | [] | 列配置数组,格式为 [{ title, dataIndex, key, width, align, ... }] | | data | Array | [] | 表格数据源数组 | | loading | Boolean | false | 加载状态,显示加载遮罩 | | rowKey | String / Function | id | 行唯一标识字段名或函数,如 "id"(row) => row.uid | | hoverable | Boolean | true | 鼠标悬停时是否高亮当前行 | | emptyText | String | 暂无数据 | 空状态时显示的文本 | | size | String | middle | 表格尺寸:small(小)/ middle(中)/ large(大) | | striped | Boolean | false | 斑马纹样式,隔行换色 | | bordered | Boolean | false | 是否显示边框 | | maxHeight | String / Number | - | 表格最大高度,超出后可滚动,支持 px 值或数字 | | selectable | Boolean | false | 是否显示复选框列,支持多选 | | selectedRowKeys | Array | - | 已选中行的 keys,v-model 双向绑定 | | showToolbar | String | - | 工具栏显示模式:show(始终显示)/ hide(始终隐藏)/ dynamic_show(滚动时显示) | | draggable | Boolean | false | 是否启用行拖动排序功能 |

列配置

| 属性 | 类型 | 说明 | |------|------|------| | key | String | 列唯一标识 | | dataIndex | String | 数据字段名 | | title | String | 列标题 | | width | String | 列宽 | | align | String | 对齐方式:left / center / right |

插槽

| 插槽名 | 说明 | 参数 | |--------|------|------| | cell-{key} | 自定义单元格 | { row, index, value } | | header-{key} | 自定义表头 | { column } |

Events

| 事件名 | 说明 | 参数 | |--------|------|------| | row-click | 行点击 | row: Object, index: Number |


QLPagination 分页

分页组件。

<template>
  <Pagination
    v-model:current-page="currentPage"
    v-model:page-size="pageSize"
    :total="100"
  />
</template>

<script setup>
import { ref } from 'vue'
const currentPage = ref(1)
const pageSize = ref(10)
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | currentPage | Number | - | 当前页码,支持 v-model:currentPage 双向绑定 | | pageSize | Number | 10 | 每页条数,支持 v-model:pageSize 双向绑定 | | total | Number | - | 数据总条数 | | variant | String | default | 分页样式变体:default(默认样式)/ simple(简洁样式)/ rounded(圆角按钮)/ mini(迷你样式) | | showTotal | Boolean | false | 是否显示数据总数,如 "共 100 条" | | showSizeChanger | Boolean | false | 是否显示每页条数选择器,可切换 10/20/50/100 等 | | showQuickJumper | Boolean | false | 是否显示快速跳转输入框,可跳转到指定页 |

Events

| 事件名 | 说明 | 参数 | |--------|------|------| | update:currentPage | 页码变化 | page: Number | | update:pageSize | 每页条数变化 | size: Number | | change | 分页变化 | page: Number, size: Number |


QLCheckbox 复选框

<template>
  <Checkbox v-model="checked" label="同意协议" />
</template>

<script setup>
import { ref } from 'vue'
const checked = ref(false)
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | Boolean | false | 选中状态,支持 v-model 双向绑定 | | value | String / Number / Boolean | - | 选项值,在 CheckboxGroupQLCheckboxGroup 组合使用时必需,用于标识该复选框的值 | | label | String | - | 标签文本,显示在复选框右侧 | | id | String | - | 表单元素的 ID 属性 | | disabled | Boolean | false | 禁用状态,禁用点击和交互 |


QLRadioGroup 单选组

<template>
  <RadioGroupQLRadioGroup
    v-model="selected"
    :options="options"
    label="选择"
    required
  />
</template>

<script setup>
import { ref } from 'vue'
const selected = ref('apple')
const options = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橘子', value: 'orange' }
]
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | String / Number / Boolean | - | 选中值,支持 v-model 双向绑定 | | options | Array | [] | 选项列表,格式为 [{ label: string, value: string/number, disabled?: boolean }] | | label | String | - | 组标签文本,显示在选项组上方 | | required | Boolean | false | 必填标记,显示红色星号 | | disabled | Boolean | false | 禁用状态,禁用整个选项组的交互 | | direction | String | vertical | 排列方向:horizontal(水平排列)/ vertical(垂直排列) | | name | String | - | 单选框的 name 属性,用于分组(通常自动生成) |


QLModal 弹窗

模态对话框组件。

<template>
  <QLButton @click="visible = true">打开弹窗</QLButton>

  <QLModal
    v-model:visible="visible"
    title="确认操作"
    width="480"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <p>确认要执行此操作吗?</p>

    <!-- 自定义底部 -->
    <template #footer>
      <QLButton variant="ghost" @click="visible = false">取消</QLButton>
      <QLButton variant="danger" @click="handleConfirm">确认删除</QLButton>
    </template>
  </QLModal>
</template>

<script setup>
import { ref } from 'vue'
const visible = ref(false)
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | visible | Boolean | - | 是否显示,支持 v-model 双向绑定 | | title | String | - | 对话框标题文本 | | width | String / Number | 520 | 对话框宽度,支持 px 值或百分比字符串如 "80%" | | closable | Boolean | true | 是否显示右上角关闭按钮 | | header | Boolean | true | 是否显示顶部标题栏区域 | | maskClosable | Boolean | true | 点击遮罩层是否关闭对话框 | | footer | Boolean | true | 是否显示底部按钮区域(确定/取消) | | escClosable | Boolean | true | 是否支持按 ESC 键关闭对话框 |

Events

| 事件名 | 说明 | |--------|------| | update:visible | 显示状态变化 | | ok | 点击确定 | | cancel | 点击取消 | | close | 关闭 |

插槽

| 插槽名 | 说明 | |--------|------| | default | 内容 | | header | 自定义头部 | | footer | 自定义底部 |


QLDrawer 抽屉

侧边抽屉组件。

<template>
  <Drawer
    v-model:visible="visible"
    title="详情"
    placement="right"
    width="400"
  >
    <p>抽屉内容</p>
  </Drawer>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | visible | Boolean | - | 是否显示,支持 v-model 双向绑定 | | title | String | - | 抽屉标题文本 | | width | String / Number | 400 | 抽屉宽度,支持 px 值或百分比字符串 | | placement | String | right | 抽屉滑出方向:left(从左侧滑出)/ right(从右侧滑出) | | closable | Boolean | true | 是否显示右上角关闭按钮 | | maskClosable | Boolean | true | 点击遮罩层是否关闭抽屉 | | container | String / Object / HTMLElement | body | 挂载容器,传 'body' 或 DOM 元素引用 | | zIndex | Number | - | 抽屉的 z-index 层级值 |


QLConfirmDialog 确认对话框

用于危险操作确认的对话框。

<template>
  <QLButton variant="danger" @click="visible = true">删除</QLButton>

  <QLConfirmDialog
    v-model:visible="visible"
    title="删除确认"
    description="确定要删除这条记录吗?此操作不可撤销。"
    type="danger"
    confirm-text="确认删除"
    @confirm="handleDelete"
  />
</template>

<script setup>
import { ref } from 'vue'
const visible = ref(false)
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | visible | Boolean | false | 是否显示,支持 v-model 双向绑定 | | title | String | 确认操作 | 对话框标题文本 | | description | String | - | 描述信息,说明文字显示在标题下方 | | type | String | danger | 对话框类型:danger(危险操作红色)/ warning(警告黄色)/ info(信息蓝色)/ success(成功绿色) | | confirmText | String | 确认 | 确认按钮的自定义文本 | | cancelText | String | 取消 | 取消按钮的自定义文本 | | showConfirm | Boolean | true | 是否显示确认按钮 | | showCancel | Boolean | true | 是否显示取消按钮 | | showClose | Boolean | true | 是否显示关闭按钮 | | showIcon | Boolean | true | 是否显示类型对应的图标 | | confirmVariant | String | danger | 确认按钮样式:primary / secondary / outline / ghost / danger / neutral / text | | cancelVariant | String | secondary | 取消按钮样式 | | confirmLoading | Boolean | false | 确认按钮加载状态 | | loading | Boolean | false | 整体加载状态,显示加载遮罩 | | escClosable | Boolean | true | 是否支持按 ESC 键关闭对话框 |

Events

| 事件名 | 说明 | |--------|------| | confirm | 点击确认 | | cancel | 点击取消 |


QLStatCard 统计卡片

用于展示统计数据的卡片组件。

<template>
  <div class="grid grid-cols-4 gap-4">
    <StatCardQLStatCard
      title="用户总数"
      value="12,345"
      :icon="Users"
      color="brand"
      trend="up"
      trend-value="+12%"
    />
    <StatCardQLStatCard
      title="活跃用户"
      value="8,234"
      :icon="Activity"
      color="jade"
    />
  </div>
</template>

<script setup>
import { Users, Activity } from 'lucide-vue-next'
</script>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | String | - | 统计卡片标题 | | value | String / Number | - | 统计数值,可为数字或字符串 | | icon | Object / Function / String | - | 图标组件,支持 lucide-vue-next 图标 | | color | String | brand | 主题颜色:brand(品牌蓝)/ purple(紫色)/ amber(琥珀色)/ jade(玉色)/ danger(危险红) | | trend | String | - | 趋势方向:up(上升)/ down(下降) | | trendValue | String | - | 趋势数值,如 "+12%""-5%" | | loading | Boolean | false | 加载状态,显示骨架屏占位 | | shape | String | - | 装饰形状:circle(圆形)/ rounded-rect(圆角矩形)/ rounded-triangle(圆角三角形)/ rounded-pentagram(五角星)/ rounded-diamond(菱形) | | shapeSize | String | md | 装饰形状大小:sm(小)/ md(中)/ lg(大) | | shapePositionX | String | - | 装饰横向位置:left(左)/ center-left(左中)/ center(居中)/ center-right(右中)/ right(右) | | shapePositionY | String | - | 装饰纵向位置:top(上)/ center(中)/ bottom(下) | | shapeX | Number | - | 装饰横向像素偏移,正值右移,优先级高于 shapePositionX | | shapeY | Number | - | 装饰纵向像素偏移,正值下移,优先级高于 shapePositionY | | randomShape | Boolean | false | 是否随机选择装饰形状 | | randomColor | Boolean | false | 是否随机选择装饰颜色 | | clickable | Boolean | false | 是否可点击,显示hover效果 |


QLTag 标签

<template>
  <Tag color="default">默认</Tag>
  <Tag color="brand">品牌</Tag>
  <Tag color="success">成功</Tag>
  <Tag color="warning">警告</Tag>
  <Tag color="danger">危险</Tag>
  <Tag color="info">信息</Tag>
  <Tag color="brand" closable @close="handleClose">可关闭</Tag>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | color | String | default | 标签颜色:default(默认灰色)/ brand(品牌蓝)/ success(成功绿)/ warning(警告黄)/ danger(危险红)/ info(信息蓝) | | size | String | md | 标签尺寸:sm(小)/ md(中)/ lg(大) | | closable | Boolean | false | 是否显示关闭按钮,点击可移除标签 | | bordered | Boolean | true | 是否显示边框 | | randomColor | Boolean | false | 是否随机选择颜色,每次渲染随机分配颜色 |


QLAlert 提示

<template>
  <Alert type="info" title="信息提示">这是一条信息提示</Alert>
  <Alert type="success" title="成功">操作成功</Alert>
  <Alert type="warning" title="警告" closable>请注意</Alert>
  <Alert type="error" title="错误">操作失败</Alert>
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | String | info | 提示类型:info(信息提示)/ success(成功提示)/ warning(警告提示)/ error(错误提示) | | title | String | - | 标题文本,加粗显示 | | closable | Boolean | false | 是否显示关闭按钮,点击可隐藏提示 | | showIcon | Boolean | false | 是否显示类型对应的图标 | | banner | Boolean | false | 是否以横幅形式显示,固定宽度而非撑满容器 |


QLSpin 加载

<template>
  <Spin size="sm" />
  <Spin size="md" tip="加载中..." />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | size | String | md | 加载指示器尺寸:sm(小)/ md(中)/ lg(大) | | tip | String | - | 加载提示文字,显示在加载图标下方 | | icon | String | - | 加载图标名称,来自 icons.js 映射表,默认使用旋转动画图标 |


QLEmpty 空状态

<Empty description="暂无数据" />

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | description | String | 暂无数据 | 描述文本,显示在空状态图片下方 | | image | String | - | 自定义图片地址,不传则显示默认空状态图标 |


QLAvatar 头像

<template>
  <Avatar size="sm" />
  <Avatar size="md" />
  <Avatar size="lg" />
  <Avatar src="/avatar.jpg" size="lg" />
</template>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | String | - | 头像图片地址 | | alt | String | - | 图片 alt 文本,用于无图片时显示 | | size | String | md | 头像尺寸:xs(超小 24px)/ sm(小 32px)/ md(中 40px)/ lg(大 64px)/ xl(超大 96px) | | shape | String | circle | 头像形状:circle(圆形)/ square(方形)/ rounded(圆角矩形) | | zoomable | Boolean | true | 鼠标悬停时是否放大图片 |


QLTooltip 提示

<Tooltip content="提示内容" placement="top">
  <QLButton>Hover me</QLButton>
</Tooltip>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | content | String | - | 提示文本内容 | | placement | String | top | 提示框弹出位置:top(上方)/ bottom(下方)/ left(左侧)/ right(右侧) | | delay | Number | - | 延迟显示时间(毫秒),鼠标移入后等待指定时间才显示提示 |


布局组件

QLMainLayout 主布局

后台管理系统主布局,包含侧边栏、顶栏、内容区。

<template>
  <MainLayoutQLMainLayout>
    <router-view />
  </MainLayoutQLMainLayout>
</template>

QLSidebar 侧边栏

可折叠的多级菜单侧边栏。

<template>
  <Sidebar :menus="menuData" />
</template>

<script setup>
import { LayoutDashboard, Settings, Users, Shield } from 'lucide-vue-next'

const menuData = [
  {
    title: '仪表盘',
    icon: LayoutDashboard,
    path: '/dashboard'
  },
  {
    title: '系统管理',
    icon: Settings,
    children: [
      { title: '用户管理', path: '/system/users' },
      { title: '角色管理', path: '/system/roles' }
    ]
  }
]
</script>

菜单数据格式

{
  title: String,      // 菜单标题
  icon: Object,       // 图标组件(lucide-vue-next)
  path: String,       // 路由路径(可选)
  children: Array     // 子菜单(可选)
}

QLHeader 顶栏

顶部导航栏,包含面包屑、日期、全屏按钮。

<Header />

Composables

usePagination 分页请求

import { usePagination } from 'qinglin-ui'

const { data, loading, pagination, refresh } = usePagination(
  async ({ page, pageSize }) => {
    const res = await api.getList({ page, pageSize })
    return { list: res.list, total: res.total }
  }
)

useForm 表单验证

import { useForm } from 'qinglin-ui'

const { values, errors, isValid, handleSubmit } = useForm(
  { username: '', password: '' },
  {
    username: { required: true, message: '请输入用户名' },
    password: { required: true, message: '请输入密码' }
  }
)

await handleSubmit(async (data) => {
  await api.login(data)
})

usePermission 权限判断

import { usePermission } from 'qinglin-ui'

const { hasPermission, hasRole } = usePermission()

if (hasPermission('system:user:add')) {
  // 显示添加按钮
}

useTheme 主题切换

import { useTheme } from 'qinglin-ui'

const { theme, themes, setTheme } = useTheme()

// 切换主题
setTheme('green')  // blue | green | purple | orange | rose

权限校验

模板中用 usePermission composable + v-if 控制元素显隐,比指令更直观、更易调试

<script setup>
import { usePermission } from 'qinglin-ui'
const { hasPermission, hasAnyPermission, hasRole } = usePermission()
</script>

<template>
  <button v-if="hasPermission('system:user:add')">添加用户</button>
  <button v-if="hasAnyPermission(['system:user:add', 'system:user:edit'])">操作</button>
  <button v-if="hasRole('admin')">管理设置</button>
</template>

主题定制

CSS 变量

在项目根目录创建 theme.css 覆盖默认变量:

:root {
  /* 品牌色 */
  --ql-brand-50: #eff6ff;
  --ql-brand-100: #dbeafe;
  --ql-brand-200: #bfdbfe;
  --ql-brand-300: #93c5fd;
  --ql-brand-400: #60a5fa;
  --ql-brand-500: #3b82f6;
  --ql-brand-600: #2563eb;
  --ql-brand-700: #1d4ed8;
  --ql-brand-800: #1e40af;
  --ql-brand-900: #1e3a8a;

  /* 成功色 */
  --ql-success-500: #22c55e;
  --ql-success-600: #16a34a;

  /* 警告色 */
  --ql-warning-500: #f59e0b;
  --ql-warning-600: #d97706;

  /* 危险色 */
  --bh-danger-500: #ef4444;
  --bh-danger-600: #dc2626;
}

运行时切换主题

import { useTheme } from 'qinglin-ui'

const { setTheme } = useTheme()
setTheme('purple')

工具函数

auth 认证工具

import { getToken, setToken, removeToken } from 'qinglin-ui'

tree 树形工具

import { arrayToTree, treeToArray } from 'qinglin-ui'

// 数组转树
const tree = arrayToTree(list, { id: 'id', parentId: 'parentId' })

// 树转数组
const flat = treeToArray(tree)

项目结构

qinglin-ui/
├── src/
│   ├── assets/styles/          # 设计系统样式
│   │   ├── theme.css           # CSS 变量定义
│   │   ├── base.css            # 基础样式重置
│   │   └── index.css           # Tailwind 入口
│   ├── components/             # UI 组件
│   │   ├── Alert/
│   │   ├── Avatar/
│   │   ├── Button/
│   │   ├── Calendar/
│   │   ├── Card/
│   │   ├── Carousel/
│   │   ├── Checkbox/
│   │   ├── Collapse/
│   │   ├── ColorPicker/
│   │   ├── ConfirmDialog/
│   │   ├── DatePicker/
│   │   ├── Drawer/
│   │   ├── Dropdown/
│   │   ├── Empty/
│   │   ├── Form/
│   │   ├── Icon/
│   │   ├── Image/
│   │   ├── Input/
│   │   ├── List/
│   │   ├── Menu/
│   │   ├── Modal/
│   │   ├── Pagination/
│   │   ├── Popconfirm/
│   │   ├── Progress/
│   │   ├── RadioGroup/
│   │   ├── Rate/
│   │   ├── Select/
│   │   ├── Spin/
│   │   ├── StatCard/
│   │   ├── Steps/
│   │   ├── Switch/
│   │   ├── Table/
│   │   ├── Tabs/
│   │   ├── Tag/
│   │   ├── Timeline/
│   │   ├── TimePicker/
│   │   ├── Tooltip/
│   │   ├── TreeSelect/
│   │   └── Upload/
│   ├── composables/            # 组合式函数
│   │   ├── useApp.js
│   │   ├── useForm.js
│   │   ├── usePagination.js
│   │   ├── usePermission.js
│   │   └── useUser.js
│   ├── directives/             # 指令
│   │   └── permission.js
│   ├── layout/                 # 布局组件
│   │   ├── Header/
│   │   ├── MainLayout/
│   │   └── Sidebar/
│   ├── theme/                  # 主题管理
│   │   └── index.js
│   ├── utils/                  # 工具函数
│   │   ├── auth.js
│   │   ├── request.js
│   │   ├── router.js
│   │   └── tree.js
│   ├── router/                 # 路由
│   │   └── index.js
│   ├── index.js                # 库入口
│   └── playground/             # 预览应用
│       ├── main.js
│       └── App.vue
├── package.json
└── README.md

开发指南

启动开发服务器

npm run dev

访问 http://localhost:5173 查看组件预览。

构建库

npm run build:lib

构建产物位于 dist/ 目录,包含 ES 和 UMD 格式。

添加新组件

  1. src/components/ 下创建组件目录
  2. 创建组件文件 Xxx.vue
  3. 创建导出文件 index.js
  4. src/components/index.js 中添加导出
  5. src/index.js 中注册组件

License

MIT

组件清单(44 个)

所有组件在模板里以 <QLXxx> 形式使用,导入时用底层 PascalCase 名(_Xxx)。

| 组件 | 描述 | 公共标签 | 关键属性 | |------|------|----------|----------| | 按钮组件 | 支持多种变体和尺寸,包含加载状态 | <QLButton> | variant: 变体:primary/secondary/outline/ghost/danger/neutral/text;size: 尺寸:sm/md/lg;block: 是否撑满宽度 | | 图标组件 | 图标组件 | <QLIcon> | name: 图标名称(Lucide 图标名,如 'User', 'Settings');size: 尺寸预设 sm/md/lg/xl 或直接传数字;color: 颜色(CSS 颜色值或 Tailwind 类) | | 输入框组件 | 输入框组件 | <QLInput> | | | 选择器组件 | 下拉选择器,支持单选/多选、搜索过滤、清空等功能 | <QLSelect> | | | 复选框组件 | 复选框,支持 v-model 双向绑定,也可在 _CheckboxGroup 内使用 | <QLCheckbox> | | | 开关组件 | 布尔值切换开关,支持多种颜色、尺寸、loading 状态和文字标签 | <QLSwitch> | modelValue: 开关状态(v-model);disabled: 是否禁用;loading: 是否加载中 | | 评分组件 | 星级评分,支持半星 | <QLRate> | modelValue: 当前评分(v-model);count: 星星总数;allowHalf: 是否允许半星 | | 上传组件 | 文件上传,支持拖拽、多文件、预览 | <QLUpload> | modelValue: 已上传文件列表(v-model);accept: 接受的文件类型;multiple: 是否多选 | | 表单容器组件 | 表单容器,提供布局和验证状态管理 | <QLForm> | model: 表单数据模型;rules: 表单验证规则;layout: 布局方式:horizontal/vertical/inline | | 表格组件 | 功能完整的表格组件,支持树形数据、单元格合并、分页、选择、行拖动排序 | <QLTable> | | | 分页组件 | 列表分页导航,支持多种样式 | <QLPagination> | currentPage: 当前页(v-model);pageSize: 每页条数(v-model);total: 总条数 | | 标签组件 | 标签组件,支持多种颜色和尺寸 | <QLTag> | color: 颜色:default/brand/success/warning/danger/info;size: 尺寸:sm/md/lg;closable: 是否可关闭 | | 提示框组件 | 提示/警告信息展示组件,支持四种类型 | <QLAlert> | type: 类型:info/success/warning/error;title: 标题;closable: 是否可关闭 | | 统计卡片组件 | 数据统计卡片,支持趋势展示和多种装饰背景形状 | <QLStatCard> | title: 标题;value: 数值;icon: 图标组件 | | 头像组件 | 用户头像展示,支持图片和默认图标 | <QLAvatar> | src: 图片地址;alt: 图片 alt 文本;size: 尺寸:xs/sm/md/lg/xl | | 徽标组件 | 在元素右上角显示徽标数字/状态点 | <QLBadge> | content: 徽标内容(数字或文本);color: 颜色:brand/success/warning/danger/info;dot: 是否显示为小圆点 | | Image Component | Image component with lazy loading, placeholder, error state and fullscreen preview support. | <QLImage> | src: Image URL;alt: Alt text;placeholder: Placeholder image URL | | 列表组件 | 列表组件 | <QLList> | | | 级联选择器 | 多层级联选择,从一组相关联的数据集合中进行选择,常用于省市区、公司层级、分类等场景。 | <QLCascader> | modelValue: 选中值(v-model),单选时为单个值,multiple 时为数组;options: 级联数据 [{ value, label, children?, disabled? }];placeholder: 占位文本 | | 分割线 | 区隔内容的分割线,支持水平/垂直方向、可带文本、虚线、自定义颜色与间距 | <QLDivider> | direction: 方向:'horizontal' 水平 / 'vertical' 垂直;contentPosition: 文本位置:'left' | 'center' | 'right'(仅水平方向且有 default slot 文本时生效);type: 线型:'solid' 实线 / 'dashed' 虚线 / 'dotted' 点线 | | 树形选择器 | 树形结构下拉选择组件,支持多选、搜索、级联选中、懒加载 | <QLTreeSelect> | modelValue: 选中的节点 key 数组(v-model);treeData: 树形数据 [{key, title, children?, disabled?}];placeholder: 占位文本 | | 卡片组件 | 通用卡片容器,支持封面图、标题、操作区 | <QLCard> | title: 卡片标题;cover: 封面图 URL;bordered: 是否有边框 | | 轮播图组件 | 支持图片/视频/音频媒体轮播和自定义 DOM 轮播的通用轮播组件 | <QLCarousel> | interval: 自动播放间隔(毫秒),0 表示不自动播放;showIndicators: 是否显示指示器;showArrows: 是否显示箭头 |

⚠️ <QLCarousel> 安全提示:当 data 中包含 { type: 'dom', html: '...' } 时,组件会通过 v-html 原样渲染该 HTML 字符串。请勿将不可信来源(如用户提交内容、未过滤的接口返回)直接传入,否则会存在 XSS 风险。建议:

  • 仅传入完全可信的内容(业务侧硬编码 / 已用 DOMPurify 过滤的接口返回)
  • 或优先使用组件默认 slot 自定义轮播内容

此行为与 Element Plus / Ant Design 等同类组件保持一致。 | 折叠面板组件 | 手风琴式折叠面板,支持多面板 | <QLCollapse> | modelValue: 当前激活的面板 key(v-model);accordion: 是否手风琴模式(同时只展开一个);{Array<{key:: string, title: string}>} items - 面板数据 | | 时间轴组件 | 垂直展示时间流信息 | <QLTimeline> | {Array<{title:: string, time?: string, content?: string, color?: string}>} items - 时间轴数据;mode: 模式:left/alternate | | 步骤条组件 | 引导用户按步骤完成任务的导航组件 | <QLSteps> | current: 当前步骤(从 0 开始,v-model);{Array<{title:: string, description?: string}>} items - 步骤数据;direction: 方向:horizontal/vertical | | 进度条组件 | 展示操作进度或百分比 | <QLProgress> | percent: 百分比(0-100);color: 颜色:brand/success/warning/danger;size: 尺寸:sm/md/lg | | 空状态组件 | 数据为空时显示的空状态占位 | <QLEmpty> | description: 描述文本;image: 自定义图片地址 | | 日历面板 | 完整日历面板,支持日期选择、事件标记、范围选择、自定义单元格与本地化。 | <QLCalendar> | modelValue: 当前日期(v-model),支持 Date 对象或 YYYY-MM-DD 字符串;rangeValue: 日期范围(v-model:rangeValue),数组形式 [start, end];events: 日期事件标记 | | 颜色选择器组件 | 颜色选择器组件 | <QLColorPicker> | | | 面包屑组件 | 显示当前页面在网站中的位置导航,支持客户端路由跳转 | <QLBreadcrumb> | {Array<{title:: string, path?: string}>} items - 面包屑数据 | | 下拉菜单组件 | 点击/悬停下拉菜单 | <QLDropdown> | trigger: 触发方式:click/hover;placement: 弹出位置:bottom/bottomLeft/bottomRight | | 菜单组件 | 侧边/顶部导航菜单,支持多层嵌套 | <QLMenu> | {Array<{key,title,icon?,children?}>}: items - 菜单数据;modelValue: 当前选中 key(v-model);mode: 模式:vertical/horizontal | | 标签页组件 | 标签页切换组件,支持多种样式和位置。内容超出宽度时显示左右滚动按钮。 | <QLTabs> | modelValue: 当前激活的标签值(v-model);type: 标签类型:line/card/border-card;position: 标签位置:top/bottom/left/right | | 模态对话框组件 | 模态对话框,支持遮罩点击关闭、ESC 键关闭、自定义页眉页脚 | <QLModal> | visible: 是否显示(v-model);title: 标题文本;width: 对话框宽度 | | 抽屉组件 | 抽屉组件 | <QLDrawer> | | | 文字提示组件 | 鼠标悬停时显示提示信息 | <QLTooltip> | content: 提示内容;placement: 位置:top/bottom/left/right;delay: 延迟显示时间(毫秒) | | 加载动画组件 | 加载动画组件 | <QLSpin> | size: 尺寸:sm/md/lg;tip: 加载提示文本;icon: 加载图标名(来自 icons.js 映射,如 'loader'、'spinner'、'refresh-cw') | | 消息提示组件 | 通过命令调用的全局消息提示 | <QLMessage> | | | 气泡确认框 | 点击元素弹出确认气泡,常用于危险操作二次确认 | <QLPopconfirm> | title: 确认提示文本;confirmText: 确认按钮文本;cancelText: 取消按钮文本 | | 日期选择器 | 日期选择器 | <QLDatePicker> | | | 时间选择器 | 时间选择组件,弹出时间面板选择时分秒 | <QLTimePicker> | modelValue: 选中时间(v-model),格式 HH:mm / HH:mm:ss;placeholder: 占位文本;disabled: 是否禁用 | | 栅格容器 | 24 列栅格,支持自定义间距与列数(cols)。 | <QLGrid> | cols: 总列数(默认 24,常见:12、24);gap: 列与行之间的统一间距(px),默认 0;columnGap: 列间距(px),优先级高于 gap | | 单选组组件 | 单选按钮组,管理一组 _Radio 的选中状态,支持 v-model 双向绑定。 | <QLRadioGroup> | modelValue: 选中值(v-model);label: 组标签文本;{Array<{label:: string, value: string|number}>} options - 选项列表(自动渲染) |

自动生成自 scripts/gen-readme.cjs。要更新:npm run gen:readme