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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@zjl_npm/basicui

v1.10.2

Published

A Vue 3 UI component library with BasicTable, BaseDialog, ImageUpload, FileUpload, BaseForm, BasicEcharts, BLInput, BLInputTag, BLInputNumber, QuotationApprovalDialog, Pagination and RightToolbar

Readme

@zjl_npm/basicui

一个基于 Vue 3 + Element Plus 的企业级 UI 组件库,提供表格、对话框、文件上传、表单、图表等常用组件。

📦 安装

npm install @zjl_npm/basicui vue element-plus echarts vue-router
# 或
pnpm add @zjl_npm/basicui vue element-plus echarts vue-router
# 或
yarn add @zjl_npm/basicui vue element-plus echarts vue-router

🚀 快速开始

1. 引入样式

// main.ts
import '@zjl_npm/basicui/style.css'

2. 全局注册(可选)

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { install } from '@zjl_npm/basicui'

const app = createApp(App)
app.use(install) // 全局注册所有组件
app.mount('#app')

3. 按需引入(推荐)

<script setup lang="ts">
import { 
  BasicTable, 
  BaseDialog, 
  ImageUpload, 
  FileUpload,
  BaseForm,
  BasicEcharts,
  BLInput,
  BLInputTag,
  BLInputNumber,
  QuotationApprovalDialog,
  Pagination,
  RightToolbar
} from '@zjl_npm/basicui'
import '@zjl_npm/basicui/style.css'
</script>

📚 功能组件列表

📊 表格组件

  • BasicTable - 功能完整的表格组件,支持搜索、分页、排序、多选等
  • Pagination - 分页组件
  • RightToolbar - 右侧工具栏组件

📝 表单组件

  • BaseDialog - 支持表单配置的对话框组件
  • BaseForm - 基础表单组件
  • BLInput - 输入框组件
  • BLInputTag - 标签输入组件
  • BLInputNumber - 数字输入组件

📈 图表组件

  • BasicEcharts - 基于 ECharts 的图表组件

📁 上传组件

  • ImageUpload - 图片上传组件,支持预览、多图上传
  • FileUpload - 文件上传组件,支持拖拽上传

💬 对话框组件

  • QuotationApprovalDialog - 报价审批对话框

📚 组件文档

BasicTable - 表格组件

功能完整的表格组件,支持搜索、分页、排序、多选等。

基础用法

<template>
  <BasicTable
    :table-data="tableData"
    :columns="columns"
    :actions="actions"
    :query-config="queryConfig"
    :query-size="querySize"
    :show-pagination="true"
    :query-config-ststus="true"
    @page-change="handlePageChange"
    @selection-change="handleSelectionChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BasicTable } from '@zjl_npm/basicui'
import type { Column, QueryConfigItem, QuerySize } from '@zjl_npm/basicui'

// 表格数据
const tableData = ref([
  { id: 1, name: '张三', age: 25, email: '[email protected]' },
  { id: 2, name: '李四', age: 30, email: '[email protected]' }
])

// 列配置
const columns: Column[] = [
  { prop: 'name', label: '姓名', width: '120px', sortable: true },
  { prop: 'age', label: '年龄', width: '100px', align: 'center' },
  { prop: 'email', label: '邮箱', width: '200px' }
]

// 操作按钮配置
const actions = [
  {
    label: '编辑',
    type: 'primary',
    size: 'small',
    action: (row: any) => {
      console.log('编辑', row)
    }
  },
  {
    label: '删除',
    type: 'danger',
    size: 'small',
    action: (row: any) => {
      console.log('删除', row)
    }
  }
]

// 搜索配置
const queryConfig: QueryConfigItem[] = [
  {
    type: 'el-input',
    prop: 'name',
    label: '姓名',
    props: {
      placeholder: '请输入姓名',
      clearable: true
    }
  },
  {
    type: 'el-select',
    prop: 'age',
    label: '年龄',
    props: {
      placeholder: '请选择年龄',
      options: [
        { label: '18-25', value: '18-25' },
        { label: '26-35', value: '26-35' }
      ]
    }
  }
]

// 分页配置
const querySize: QuerySize = {
  pageNum: 1,
  pageSize: 10
}

// 分页事件
const handlePageChange = (page: QuerySize) => {
  console.log('分页变化', page)
  querySize.pageNum = page.pageNum
  querySize.pageSize = page.pageSize
  // 重新请求数据
}

// 多选事件
const handleSelectionChange = (selection: any[]) => {
  console.log('选中的行', selection)
}
</script>

Props

| 参数 | 说明 | 类型 | 默认值 | 必填 | |------|------|------|--------|------| | tableData | 表格数据 | any[] | [] | ✅ | | columns | 列配置 | Column[] | [] | ✅ | | actions | 操作按钮配置 | ActionControl[] | [] | ✅ | | border | 是否显示边框 | boolean | false | ❌ | | stripe | 是否显示斑马纹 | boolean | false | ❌ | | showSelection | 是否显示多选框 | boolean | false | ❌ | | selectionType | 选择类型 | string | 'selection' | ❌ | | rowKey | 行数据的 Key | string | 'id' | ❌ | | height | 表格高度 | string | - | ❌ | | actionLabel | 操作列标题 | string | '操作' | ❌ | | actionWidth | 操作列宽度 | string | - | ❌ | | overflowhidden | 是否启用文本溢出隐藏 | boolean | false | ❌ | | queryConfigStstus | 是否显示搜索表单 | boolean | false | ❌ | | showPagination | 是否显示分页 | boolean | false | ❌ | | queryConfig | 搜索表单配置 | QueryConfigItem[] | [] | ❌ | | querySize | 分页参数 | QuerySize | { pageNum: 1, pageSize: 10 } | ❌ |


BaseForm - 基础表单组件

支持多种表单控件的表单组件。

基础用法

<template>
  <BaseForm
    :form-config="formConfig"
    :form-data="formData"
    @submit="handleSubmit"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BaseForm } from '@zjl_npm/basicui'
import type { FormConfigItem } from '@zjl_npm/basicui'

const formData = ref({})

// 表单配置
const formConfig: FormConfigItem[] = [
  {
    type: 'el-input',
    prop: 'name',
    label: '姓名',
    required: true,
    props: {
      placeholder: '请输入姓名',
      clearable: true
    }
  },
  {
    type: 'el-input-number',
    prop: 'age',
    label: '年龄',
    required: true,
    props: {
      placeholder: '请输入年龄',
      min: 0,
      max: 150
    }
  }
]

// 提交事件
const handleSubmit = (data: any) => {
  console.log('提交数据', data)
}
</script>

BasicEcharts - 图表组件

基于 ECharts 的图表组件,支持多种图表类型。

基础用法

<template>
  <BasicEcharts
    :chart-data="chartData"
    :basic-config="basicConfig"
    width="600px"
    height="400px"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BasicEcharts } from '@zjl_npm/basicui'
import type { ChartData, BasicConfig } from '@zjl_npm/basicui'

const chartData = ref<ChartData>({
  xAxis: ['周一', '周二', '周三', '周四', '周五'],
  series: [
    {
      name: '销售额',
      data: [120, 200, 150, 80, 70]
    }
  ]
})

const basicConfig = ref<BasicConfig>({
  title: '销售数据统计',
  type: 'line'
})
</script>

BLInput - 输入框组件

增强的输入框组件,支持多种输入类型。

基础用法

<template>
  <BLInput
    v-model="inputValue"
    placeholder="请输入内容"
    clearable
    @change="handleChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BLInput } from '@zjl_npm/basicui'

const inputValue = ref('')

const handleChange = (value: string) => {
  console.log('输入值变化', value)
}
</script>

BLInputTag - 标签输入组件

支持标签输入和管理的组件。

基础用法

<template>
  <BLInputTag
    v-model="tags"
    placeholder="输入标签后按回车添加"
    @change="handleTagsChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BLInputTag } from '@zjl_npm/basicui'

const tags = ref<string[]>(['标签1', '标签2'])

const handleTagsChange = (newTags: string[]) => {
  console.log('标签变化', newTags)
}
</script>

BLInputNumber - 数字输入组件

增强的数字输入组件,支持步进、范围限制等。

基础用法

<template>
  <BLInputNumber
    v-model="numberValue"
    :min="0"
    :max="100"
    :step="1"
    @change="handleNumberChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BLInputNumber } from '@zjl_npm/basicui'

const numberValue = ref(0)

const handleNumberChange = (value: number) => {
  console.log('数字变化', value)
}
</script>

QuotationApprovalDialog - 报价审批对话框

专门用于报价审批流程的对话框组件。

基础用法

<template>
  <QuotationApprovalDialog
    v-model:visible="dialogVisible"
    :quotation-data="quotationData"
    @approve="handleApprove"
    @reject="handleReject"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { QuotationApprovalDialog } from '@zjl_npm/basicui'

const dialogVisible = ref(false)
const quotationData = ref({
  id: 1,
  title: '项目报价',
  amount: 10000,
  description: '项目详细描述'
})

const handleApprove = (data: any) => {
  console.log('审批通过', data)
  dialogVisible.value = false
}

const handleReject = (data: any) => {
  console.log('审批拒绝', data)
  dialogVisible.value = false
}
</script>

Pagination - 分页组件

功能完整的分页组件,支持多种分页模式。

基础用法

<template>
  <Pagination
    :current-page="currentPage"
    :page-size="pageSize"
    :total="total"
    @page-change="handlePageChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Pagination } from '@zjl_npm/basicui'

const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(100)

const handlePageChange = (page: number, size: number) => {
  currentPage.value = page
  pageSize.value = size
  // 重新加载数据
}
</script>

RightToolbar - 右侧工具栏组件

表格右侧工具栏,支持多种操作按钮。

基础用法

<template>
  <RightToolbar
    :columns="columns"
    @refresh="handleRefresh"
    @export="handleExport"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { RightToolbar } from '@zjl_npm/basicui'

const columns = ref([
  { prop: 'name', label: '姓名' },
  { prop: 'age', label: '年龄' }
])

const handleRefresh = () => {
  console.log('刷新数据')
}

const handleExport = () => {
  console.log('导出数据')
}
</script>

BaseDialog - 对话框组件

支持表单配置的对话框组件,自动生成表单字段。

基础用法

<template>
  <el-button @click="dialogVisible = true">打开对话框</el-button>
  
  <BaseDialog
    v-model:visible="dialogVisible"
    title="新增用户"
    :dialog-form-config="dialogFormConfig"
    :form-data="formData"
    @submit="handleSubmit"
    @close="handleClose"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BaseDialog } from '@zjl_npm/basicui'
import type { FormConfigItem } from '@zjl_npm/basicui'

const dialogVisible = ref(false)
const formData = ref({})

// 表单配置
const dialogFormConfig: FormConfigItem[] = [
  {
    type: 'el-input',
    prop: 'name',
    label: '姓名',
    required: true,
    props: {
      placeholder: '请输入姓名',
      clearable: true
    }
  },
  {
    type: 'el-input-number',
    prop: 'age',
    label: '年龄',
    required: true,
    props: {
      placeholder: '请输入年龄',
      min: 0,
      max: 150
    }
  }
]

// 提交事件
const handleSubmit = (data: any) => {
  console.log('提交数据', data)
  dialogVisible.value = false
}

// 关闭事件
const handleClose = () => {
  formData.value = {}
}
</script>

ImageUpload - 图片上传组件

支持图片预览、多图上传的图片上传组件。

基础用法

<template>
  <ImageUpload
    v-model="imageList"
    :limit="9"
    :max-size="10"
    action="/api/upload"
    @success="handleSuccess"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { ImageUpload } from '@zjl_npm/basicui'

const imageList = ref<string[]>([])

const handleSuccess = (url: string) => {
  console.log('上传成功', url)
}
</script>

FileUpload - 文件上传组件

支持拖拽上传、文件列表展示的文件上传组件。

基础用法

<template>
  <FileUpload
    v-model="fileList"
    :limit="5"
    :max-size="50"
    action="/api/upload/file"
    @success="handleSuccess"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@zjl_npm/basicui'

const fileList = ref<string[]>([])

const handleSuccess = (url: string) => {
  console.log('上传成功', url)
}
</script>

🎣 Hooks 使用

useCrud - CRUD 操作 Hook

封装了增删改查的通用逻辑。

<script setup lang="ts">
import { useCrud } from '@zjl_npm/basicui'

const {
  tableData,        // 表格数据
  dialogVisible,    // 对话框显示状态
  formData,         // 表单数据
  loading,          // 加载状态
  querySize,        // 分页参数
  openAdd,          // 打开新增对话框
  openEdit,         // 打开编辑对话框
  submitForm,       // 提交表单
  handleDelete,     // 删除
  handleSearch,     // 搜索
  handlePageChange, // 分页
  listData          // 获取列表数据
} = useCrud(
  ref([]),  // 操作按钮配置
  {
    listApi: async (params) => {
      // 获取列表 API
      const res = await fetch('/api/list', { params })
      return res.data
    },
    addDataApi: async (data) => {
      // 新增 API
      return await fetch('/api/add', { method: 'POST', body: JSON.stringify(data) })
    },
    editDataApi: async (data) => {
      // 编辑 API
      return await fetch('/api/edit', { method: 'PUT', body: JSON.stringify(data) })
    }
  }
)
</script>

useTableMaxHeight - 表格高度计算 Hook

自动计算表格最大高度。

<script setup lang="ts">
import { useTableMaxHeight } from '@zjl_npm/basicui'

const { tableMaxHeight } = useTableMaxHeight()
// tableMaxHeight 是响应式的,值为窗口高度的 65%
</script>

dictionaryRegistration - 字典注册

自动为查询配置注册字典数据。

import { dictionaryRegistration } from '@zjl_npm/basicui'

// 注册字典
dictionaryRegistration(
  ['color'], // 字典编码数组
  ['color111'], // 对应的属性名数组
  queryConfig.value, // 查询配置数组
  DictAPI //字典接口api
)

🔧 完整示例

完整的 CRUD 示例

<template>
  <div>
    <el-button type="primary" @click="openAdd">新增</el-button>
    
    <BasicTable
      :table-data="tableData"
      :columns="columns"
      :actions="actions"
      :query-config="queryConfig"
      :query-size="querySize"
      :show-pagination="true"
      :query-config-ststus="true"
      :loading="loading"
      @page-change="handlePageChange"
    />
    
    <BaseDialog
      v-model:visible="dialogVisible"
      :title="drawerTitle"
      :dialog-form-config="dialogFormConfig"
      :form-data="formData"
      @submit="submitForm"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { BasicTable, BaseDialog, useCrud } from '@zjl_npm/basicui'
import type { Column, QueryConfigItem, FormConfigItem } from '@zjl_npm/basicui'

// 列配置
const columns: Column[] = [
  { prop: 'name', label: '姓名', width: '120px' },
  { prop: 'age', label: '年龄', width: '100px' },
  { prop: 'email', label: '邮箱', width: '200px' }
]

// 操作按钮
const actions = ref([
  {
    label: '编辑',
    type: 'primary',
    size: 'small',
    action: (row: any) => openEdit(row, 'edit')
  },
  {
    label: '删除',
    type: 'danger',
    size: 'small',
    action: (row: any) => handleDelete(row)
  }
])

// 查询配置
const queryConfig: QueryConfigItem[] = [
  {
    type: 'el-input',
    prop: 'name',
    label: '姓名',
    props: { placeholder: '请输入姓名' }
  }
]

// 表单配置
const dialogFormConfig: FormConfigItem[] = [
  {
    type: 'el-input',
    prop: 'name',
    label: '姓名',
    required: true
  },
  {
    type: 'el-input-number',
    prop: 'age',
    label: '年龄',
    required: true
  }
]

// 使用 useCrud Hook
const {
  tableData,
  dialogVisible,
  formData,
  loading,
  querySize,
  drawerTitle,
  openAdd,
  openEdit,
  submitForm,
  handleDelete,
  handlePageChange
} = useCrud(actions, {
  listApi: async (params) => {
    const res = await fetch('/api/users', { params })
    return res.data
  },
  addDataApi: async (data) => {
    return await fetch('/api/users', {
      method: 'POST',
      body: JSON.stringify(data)
    })
  },
  editDataApi: async (data) => {
    return await fetch(`/api/users/${data.id}`, {
      method: 'PUT',
      body: JSON.stringify(data)
    })
  }
})
</script>

📄 License

MIT

🔗 相关链接