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

@x-infra/components

v1.0.4

Published

Vue 2 component library built with Element UI

Downloads

11

Readme

Components

Vue 2 组件库,基于 Element UI 构建。

📦 安装

npm install @x-infra/components
# 或
pnpm add @x-infra/components
# 或
yarn add @x-infra/components

🔧 依赖要求

  • Vue >= 2.7.0
  • Element UI >= 2.15.13

🚀 快速开始

完整引入

import Vue from 'vue'
import ElementUI from 'element-ui'
import Components from '@x-infra/components'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)
Vue.use(Components)

按需引入

import Vue from 'vue'
import { xForm, xTable } from '@x-infra/components'

// 注册单个组件
Vue.component('XForm', xForm)
Vue.component('XTable', xTable)

📚 组件列表

XTable 表格组件

Props

| 参数 | 说明 | 类型 | 默认值 | | ------------------ | ----------------------------------- | ---------- | ---------------- | | data | 表格数据,测试或不是用接口时使用 | Array | [] | | columns | 表格列配置,参数见下表 | Array | [] | | selection | 是否显示多选框 | Boolean | false | | showSelectCount | 是否显示选中数量 | Boolean | false | | selectData | 已选中的数据 | Array | [] | | rowKey | 行的 key | String | '' | | queryApi | 查询接口函数 | Function | null | | queryParams | 查询参数 | Object | {} | | formatData | 数据格式化函数 | Function | null | | showPagination | 是否显示分页 | Boolean | true | | autoRequest | 是否自动请求数据 | Boolean | false | | emptyText | 空数据提示文本 | String | '暂无相关信息' | | cacheKey | 分页缓存 key | String | '' | | paginationConfig | 分页器配置 | Object | {} | | page_size | 每页显示条数 | Number | 10 | | pageMode | 分页模式:0-分页器,1-上一页/下一页 | Number | 0 |

Events

| 事件名 | 说明 | 回调参数 | | ----------------- | -------------------- | ---------------------------- | | selectionChange | 选择项发生变化时触发 | selection - 选中的数据数组 | | rowClick | 行点击事件 | row - 当前行数据 | | rowExpand | 行展开事件 | row - 当前行数据 |

Methods

| 方法名 | 说明 | 参数 | | --- | --- | --- | | refresh | 刷新表格数据 | (cache, param) - cache: 是否使用缓存, param: 查询参数 | | handleQuery | 手动触发查询 | params - 查询参数 | | getSelectList | 获取选中的数据列表 | - | | doLayout | 对表格进行重新布局 | - | | handleClearSelection | 清空选择 | - |

Slots

| 插槽名 | 说明 | 作用域参数 | | ------------------ | ------------ | ------------------------- | | [prop] | 自定义列内容 | { row, column, $index } | | headExpandedSlot | 头部展开插槽 | { row, $index } | | endExpandedSlot | 尾部展开插槽 | - |

Columns 配置

| 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | label | 列标题 | String | - | | prop | 对应数据字段名 | String | - | | width | 列宽度 | String \| Number | - | | minWidth | 最小列宽 | String \| Number | - | | slot | 是否使用插槽自定义列内容 | Boolean | false | | formatter | 格式化函数,用于格式化单元格内容 | Function(row, column, index) | - | | showTooltip | 是否显示 tooltip(当内容过长时) | Boolean | false | | fixed | 列是否固定:left / right / true / false | String \| Boolean | false | | align | 对齐方式:left / center / right | String | left | | headerAlign | 表头对齐方式:left / center / right | String | - | | sortable | 是否可排序 | Boolean \| String | false | | resizable | 是否可以通过拖动改变列宽 | Boolean | true | | showOverflowTooltip | 当内容过长被隐藏时显示 tooltip | Boolean | false | | className | 列的 className | String | - | | labelClassName | 当前列标题的自定义类名 | String | - |

注意: columns 配置支持所有 Element UI el-table-column 组件的属性,以上为常用参数。

基础示例

<template>
	<x-table
		:columns="columns"
		:data="tableData"
		:show-pagination="true"
		@row-click="handleRowClick" />
</template>

<script>
	export default {
		data() {
			return {
				columns: [
					{ label: '姓名', prop: 'name' },
					{ label: '年龄', prop: 'age' },
					{ label: '性别', prop: 'gender' }
				],
				tableData: [
					{ name: '张三', age: 18, gender: '男' },
					{ name: '李四', age: 20, gender: '女' }
				]
			}
		},
		methods: {
			handleRowClick(row) {
				console.log('点击行:', row)
			}
		}
	}
</script>

自定义列内容

使用具名插槽对表格内容替换。

<template>
	<x-table :columns="columns" :data="tableData">
		<template #status="{ row }">
			<el-tag :type="row.status === 'active' ? 'success' : 'info'">
				{{ row.status === 'active' ? '启用' : '禁用' }}
			</el-tag>
		</template>
		<template #action="{ row }">
			<el-button size="mini" @click="handleEdit(row)">编辑</el-button>
			<el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button>
		</template>
	</x-table>
</template>

<script>
	export default {
		data() {
			return {
				columns: [
					{ label: '姓名', prop: 'name' },
					{ label: '状态', prop: 'status', slot: true },
					{ label: '操作', prop: 'action', slot: true }
				],
				tableData: [
					{ name: '张三', status: 'active' },
					{ name: '李四', status: 'inactive' }
				]
			}
		},
		methods: {
			handleEdit(row) {
				console.log('编辑:', row)
			},
			handleDelete(row) {
				console.log('删除:', row)
			}
		}
	}
</script>

XForm 表单组件

基于 Element UI Form 封装的表单组件,支持多种输入类型,简化表单开发。

Props

| 参数 | 说明 | 类型 | 默认值 | | ------------ | ---------------- | --------- | --------- | | model | 表单数据对象 | Object | {} | | columns | 表单项配置数组 | Array | [] | | gutter | 栅格间距 | Number | 60 | | showFooter | 是否显示底部按钮 | Boolean | true | | isNoLable | 是否不显示标签 | Boolean | false | | size | 表单尺寸 | String | 'small' | | rowConfig | el-row 配置 | Object | {} |

Events

| 事件名 | 说明 | 回调参数 | | -------- | ------------ | ---------------------- | | submit | 表单提交事件 | model - 表单数据对象 |

Methods

| 方法名 | 说明 | 参数 | | --------------- | ------------ | --------------- | | validate | 验证整个表单 | - | | validateField | 验证指定字段 | prop - 字段名 | | resetForm | 重置整个表单 | - | | resetField | 重置指定字段 | prop - 字段名 |

Columns 配置

| 参数 | 说明 | 类型 | 默认值 | 示例 | | --- | --- | --- | --- | --- | | label | 字段标签文本 | String | - | | prop | 字段名(对应 model 中的 key) | String | - | | type | 输入类型,见下方支持的类型 | String | 'text' | | span | 栅格占位(1-24) | Number | 24 | | offset | 栅格偏移 | Number | 0 | | showLabel | 是否显示标签 | Boolean | true | | labelWidth | 标签宽度 | String | - | | rule | 验证规则数组 | Array | [] | | options | 选项数据(select/radio/cascader 使用) | Array | [] | | config | 组件配置对象(传递给具体组件) | Object | {} | | listeners | 事件监听器对象 | Object | {} | | visible | 是否展示该表单项 | Boolean | - | | deps | 表单依赖项,填写字段名,依赖表单中具体字段变化 | Array | - | | effect | deps副作用触发,deps内容变更之后执行副作用回调,回调中接收参数item当前表单配置项的内容 data 整个表单数据 | Object | - | {name:(item,data)=>{}} |

注意:

  • config 对象中的属性会直接传递给对应的 Element UI 组件
  • listeners 对象用于绑定组件事件,如 { change: handleChange }
  • typeselectradio 时,options 格式:[{ label: '选项1', value: 'value1' }]
  • typecascader 时,options 格式遵循 Element UI Cascader 的数据格式

支持的表单类型

| 类型 | 说明 | 对应组件 | 特殊配置 | | --- | --- | --- | --- | | text | 文本输入框(默认) | el-input | 支持 type 属性(text/password/number等) | | textarea | 多行文本 | el-input | 通过 config.rows 设置行数 | | select | 下拉选择 | el-select | 需要 options 数组 | | switch | 开关 | el-switch | - | | radio | 单选按钮 | el-radio-group | 需要 options 数组 | | date | 日期选择器 | el-date-picker | 通过 config.type 设置类型(date/datetime等) | | cascader | 级联选择器 | el-cascader | 需要 options 数组(级联格式) |

基础示例

<template>
	<x-form :model="formData" :columns="columns" @submit="handleSubmit" />
</template>

<script>
	export default {
		data() {
			return {
				formData: {
					name: '',
					age: '',
					status: true
				},
				columns: [
					{
						label: '姓名',
						prop: 'name',
						type: 'text',
						rule: [{ required: true, message: '请输入姓名', trigger: 'blur' }]
					},
					{
						label: '年龄',
						prop: 'age',
						type: 'text',
						rule: [{ required: true, message: '请输入年龄', trigger: 'blur' }]
					},
					{
						label: '状态',
						prop: 'status',
						type: 'switch'
					}
				]
			}
		},
		methods: {
			handleSubmit(data) {
				console.log('提交数据:', data)
			}
		}
	}
</script>

不同表单类型配置示例

下拉选择(select)

{
	label: '城市',
	prop: 'city',
	type: 'select',
	options: [
		{ label: '北京', value: 'beijing' },
		{ label: '上海', value: 'shanghai' }
	],
	config: {
		placeholder: '请选择城市',
		clearable: true,
		filterable: true
	},
	rule: [{ required: true, message: '请选择城市', trigger: 'change' }]
}

单选按钮(radio)

{
	label: '性别',
	prop: 'gender',
	type: 'radio',
	options: [
		{ label: 'male', name: '男' },
		{ label: 'female', name: '女' }
	]
}

日期选择器(date)

{
	label: '日期',
	prop: 'date',
	type: 'date',
	config: {
		type: 'date', // date/datetime/daterange
		placeholder: '选择日期',
		format: 'yyyy-MM-dd',
		valueFormat: 'yyyy-MM-dd'
	},
	rule: [{ required: true, message: '请选择日期', trigger: 'change' }]
}

级联选择器(cascader)

{
	label: '地区',
	prop: 'region',
	type: 'cascader',
	options: [
		{
			value: 'beijing',
			label: '北京',
			children: [
				{ value: 'haidian', label: '海淀区' },
				{ value: 'chaoyang', label: '朝阳区' }
			]
		}
	],
	config: {
		placeholder: '请选择地区',
		clearable: true
	}
}

多行文本(textarea)

{
	label: '备注',
	prop: 'remark',
	type: 'textarea',
	config: {
		rows: 4,
		placeholder: '请输入备注信息',
		maxlength: 200,
		showWordLimit: true
	}
}

密码输入框

{
	label: '密码',
	prop: 'password',
	type: 'password', // text 类型,但 type 为 password
	config: {
		placeholder: '请输入密码',
		showPassword: true
	},
	rule: [
		{ required: true, message: '请输入密码', trigger: 'blur' },
		{ min: 6, max: 20, message: '密码长度为6-20位', trigger: 'blur' }
	]
}

使用表单方法

<template>
	<x-form ref="form" :model="formData" :columns="columns">
		<template #action>
			<el-button @click="validateForm">验证</el-button>
			<el-button @click="resetForm">重置</el-button>
		</template>
	</x-form>
</template>

<script>
	export default {
		data() {
			return {
				formData: {
					name: ''
				},
				columns: [
					{
						label: '姓名',
						prop: 'name',
						rule: [{ required: true, message: '请输入姓名' }]
					}
				]
			}
		},
		methods: {
			async validateForm() {
				try {
					await this.$refs.form.validate()
					console.log('验证通过')
				} catch (err) {
					console.log('验证失败', err)
				}
			},
			resetForm() {
				this.$refs.form.resetForm()
			}
		}
	}
</script>

指定类型

<template>
	<x-empty type="noAuth" />
</template>

自定义内容

<template>
	<x-empty custom>
		<div>自定义空状态内容</div>
	</x-empty>
</template>

🛠️ 开发

本地开发

# 安装依赖
pnpm install

# 启动开发服务器
pnpm dev

构建

# 构建组件库
pnpm build

构建产物会输出到 dist 目录:

  • components.es.js - ES Module 格式
  • components.umd.js - UMD 格式
  • assets/components.css - 样式文件

预览构建结果

pnpm preview

📝 项目结构

components/
├── src/
│   ├── components/      # 组件目录
│   │   ├── Table/      # 表格组件
│   │   ├── Form/       # 表单组件
│   │   └── Empty/      # 空状态组件
│   ├── index.js        # 入口文件
│   ├── App.vue         # 开发演示
│   └── main.js         # 开发入口
├── dist/               # 构建输出
├── package.json
└── vite.config.js      # Vite 配置

📄 License

ISC