qinglin-ui
v1.0.0
Published
QingLin UI 是由青林中医科技开发的企业级 Vue3 组件库
Maintainers
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 格式。
添加新组件
- 在
src/components/下创建组件目录 - 创建组件文件
Xxx.vue - 创建导出文件
index.js - 在
src/components/index.js中添加导出 - 在
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
