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

@wang-ele/form

v1.1.5

Published

根据配置生成表单,vue3 + element-plus 实现,快速开发,可扩展,开箱即可使用

Readme

Wang Form

这是一个基于 Vue 3 + Element Plus 的表单组件,可以通过配置快速生成表单。

Vue 3 + TypeScript + Vite

如果不想看下面的,可直接拉项目感受一下-可能需要安装最新依赖,尽量使用低代码看

https://gitee.com/wang-dabao1/open-source-learning-wang-ele

还有针对此项目的低代码拖拽快速生成表单-正在实时更新

https://wangweifeng.com/wang/#wang

有问题加我微信: pipishanwomenzou

使用方法

安装

npm install @wang-ele/form

引入组件和样式

有多种方式可以引入样式:

方式1:直接引入CSS文件(推荐)

import { createApp } from 'vue'
import WangForm from '@wang-ele/form'

// 重要: 引入样式文件
import '@wang-ele/form/dist/style.css'

createApp(App)
.use(ElementPlus) // ElementPlus 全局引入
.use(WangForm) // WangForm 全局引入
.mount('#app')

这俩别忘了装

"@element-plus/icons-vue": "2.3.1",

"element-plus": "2.8.7",

<template>
	<div>
		<el-card>
			<template #header>
				<el-divider content-position="left">基本信息</el-divider>
			</template>
			<!-- ref不可定义为wangForm不然会把原有标签给替换 -->
			<wang-form :form="form" ref="wang_one">
				<template #我是个插槽> 我是个插槽可以随便插东西</template>
				<template #switchRef>
					<span>&nbsp;&nbsp;开启该选项后,该Notebook实例将在运行时长超出您所选择的时长后,自动停止</span>
				</template>
				<template #radioRef>  <!-- 插槽可以插到表单后面 -->
					<el-form-item prop="numbers" v-if="form.model.env === '0'">
						<el-input min="1" style="width: 100px; margin-left: 10px" type="number" v-model="form.model.numbers"></el-input>
					</el-form-item>
				</template>
				<template #select> <!-- 插槽可以插组件变量绑定到总表单里 -->
					<algorithm
						v-model:type="form.model.isPrefab"
						v-model:id="form.model.algorithmId"
						v-model:version-id="form.model.algorithmVersionId"
					></algorithm>
				</template>
			</wang-form>
			<template #footer>
				<el-button type="primary" @click="onSubmit">确定</el-button>
				<el-button @click="onCancel">取消</el-button>
			</template>
		</el-card>
	</div>
</template>

<script setup lang="ts">
// import { Session } from '/@/utils/storage'; // 这块是根据自己项目来,主要是拿token发请求用,上传文件会用到
// import { useRouter } from 'vue-router';
// import { useDict } from '/@/hooks/systemDict'; // 这块是根据自己项目来,主要是系统字典获取
// import { bigdataDatasetTypeDetails } from '/@/api/dataService/dataSet'; // 这块是根据自己项目来,主要是后端字典获取
import { ref, reactive, computed } from 'vue';
// const router = useRouter();
const wang_one = ref();
// 定义字典演示如何加入wang-form 算法框架
// const { algorithm_framework } = useDict('algorithm_framework');

// 后端自写无分页查询接口
const datasetData: any = ref([]);
// bigdataDatasetTypeDetails({ type: '1' }).then((res) => {
// 	datasetData.value = res.data;
// });

const form: any = reactive({
	list: [
		{
			RefName: '我是个插槽',
		},
		{
			component: 'input',
			label: '任务名称',
			field: 'name',
			span: 24,
			width: 100,
			attrs: {
				placeholder: '请输入任务名称',
				maxlength: 50,
				showWordLimit: true,
				clearable: true
			},
		},
		{
			component: 'input',
			label: '长度自定义50%',
			field: 'widthTest',
			span: 24,
			width: 50,
			attrs: {
				placeholder: '请输入长度自定义',
				maxlength: 50,
				showWordLimit: true,
				clearable: true,
			},
		},
		{
			component: 'input',
			label: '长度自定义700px',
			field: 'widthTest2',
			span: 24,
			width: '700px',
			attrs: {
				placeholder: '请输入长度自定义',
				maxlength: 50,
				showWordLimit: true,
				clearable: true,
			},
		},
		{
			component: 'input',
			label: '根据屏幕自适应',
			field: 'widthTest3',
			xs: 24,
			sm: 12,
			md: 12,
			lg: 12,
			xl: 12,
			attrs: {
				placeholder: '请输入根据屏幕自适应',
				maxlength: 50,
				showWordLimit: true,
				clearable: true,
			},
		},
		{
			component: 'select',
			label: '模型类型',
			field: 'type1',
			span: 12,
			attrs: {
				placeholder: '请选择模型类型',
				clearable: true,
				filterable: true,
				label: 'label',
				value: 'value'
			},
			options: [
				{ label: '分类', value: '1' },
				{ label: '回归', value: '2' },
				{ label: '目标检测', value: '3' },
				{ label: '图像分割', value: '4' },
			],
		},
		{
			component: 'select',
			label: '带信息的下拉',
			field: 'type2',
			span: 12,
			attrs: {
				placeholder: '请选择模型类型',
				clearable: true,
				filterable: true,
				name: 'snamename',
				info: 'infos'
			},
			options: [
				{ label: '分类', value: '1', snamename: 'zh' ,infos: '这是一条信息'},
				{ label: '回归', value: '2', snamename: 'ss' ,infos: '这是一条信息'},
				{ label: '目标检测', value: '3', snamename: 'cc' ,infos: '这是一条信息'},
				{ label: '图像分割', value: '4', snamename: 'dd' ,infos: '这是一条信息'},
			],
		},
		{
			component: 'radio',
			label: '运行环境',
			field: 'env',
			span: 12,
			width: 100,
			attrs: {
				border: true,
				size: 'large',
				onChange: (val: any) => {
					val === 'cpu' ? (form.model.gpuCount = '') : null;
				},
			},
			options: [
				{ label: 'CPU', value: 'cpu' },
				{ label: 'GPU', value: 'gpu' },
			],
		},
		{
			component: 'number',
			label: '训练轮次',
			field: 'epochs',
			span: 8,
			width: 100,
			attrs: {
				min: 1,
				max: 1000,
				step: 1,
				controlsPosition: 'right',
				placeholder: '请输入训练轮次',
			},
		},
		{
			component: 'number',
			label: '批次大小',
			field: 'batchSize',
			span: 8,
			width: 100,
			attrs: {
				min: 1,
				max: 512,
				step: 1,
				controlsPosition: 'right',
				placeholder: '请输入批次大小',
			},
		},
		{
			component: 'number',
			label: 'GPU数量',
			field: 'gpuCount',
			span: 8,
			width: 100,
			attrs: {
				min: 1,
				max: 8,
				step: 1,
				controlsPosition: 'right',
				placeholder: '请输入GPU数量',
				disabled: computed(() => form.model.env === 'cpu'),
			},
		},
		{
			component: 'slider',
			label: '学习率',
			field: 'learningRate',
			span: 24,
			width: 100,
			attrs: {
				min: 0,
				max: 80,
				step: 2,
				showInput: false,
				showStops: false,
				marks: {
					0: '0',
					20: '20',
					40: '40',
					80: '80',
				},
			},
		},
		{
			component: 'checkbox',
			label: '高级选项',
			field: 'advancedOptions',
			span: 24,
			width: 100,
			attrs: {
				border: true,
			},
			options: [
				{ label: '使用预训练模型', value: 'pretrained' },
				{ label: '启用早停', value: 'earlyStop' },
				{ label: '保存检查点', value: 'checkpoint' },
				{ label: '使用混合精度', value: 'mixedPrecision' },
				{ label: '启用梯度裁剪', value: 'gradientClipping' },
			],
		},
		{
			component: 'time',
			label: '定时执行',
			field: 'scheduleTime',
			span: 12,
			width: 100,
			attrs: {
				placeholder: '请选择执行时间',
				format: 'HH:mm',
				clearable: true,
			},
		},
		{
			component: 'date',
			label: '截止日期',
			field: 'deadline',
			span: 12,
			width: 100,
			attrs: {
				type: 'date',
				placeholder: '请选择截止日期',
				clearable: true,
			},
		},
		{
			component: 'switch',
			label: '是否公开',
			field: 'isPublic',
			span: 12,
			width: 100,
			attrs: {
				activeText: '是',
				inactiveText: '否',
				inlinePrompt: true,
			},
		},
		{
			component: 'rate',
			label: '优先级',
			field: 'priority',
			span: 12,
			width: 100,
			attrs: {
				max: 3,
				texts: ['低', '中', '高'],
				showText: true,
				allowHalf: false,
			},
		},
		{
			component: 'cascader',
			label: '模型分类',
			field: 'modelCategory',
			span: 12,
			width: 100,
			attrs: {
				placeholder: '请选择模型分类',
				clearable: true,
				props: {
					expandTrigger: 'hover',
				},
			},
			options: [
				{
					value: 'cv',
					label: '计算机视觉',
					children: [
						{
							value: 'classification',
							label: '图像分类',
							children: [
								{ value: 'single', label: '单标签分类' },
								{ value: 'multi', label: '多标签分类' },
							],
						},
						{
							value: 'detection',
							label: '目标检测',
							children: [
								{ value: 'face', label: '人脸检测' },
								{ value: 'object', label: '物体检测' },
							],
						},
					],
				},
				{
					value: 'nlp',
					label: '自然语言处理',
					children: [
						{
							value: 'classification',
							label: '文本分类',
							children: [
								{ value: 'sentiment', label: '情感分析' },
								{ value: 'topic', label: '主题分类' },
							],
						},
						{
							value: 'generation',
							label: '文本生成',
							children: [
								{ value: 'summary', label: '文本摘要' },
								{ value: 'translation', label: '机器翻译' },
							],
						},
					],
				},
			],
		},
		{
			component: 'tree',
			label: '预训练模型',
			field: 'pretrainedModel',
			span: 12,
			width: 100,
			attrs: {
				placeholder: '请选择预训练模型',
				checkStrictly: true,
				showCheckbox: true,
				nodeKey: 'id',
				props: {
					label: 'name',
					children: 'children',
				},
			},
			options: [
				{
					id: 1,
					name: 'ResNet系列',
					children: [
						{ id: 2, name: 'ResNet18' },
						{ id: 3, name: 'ResNet34' },
						{ id: 4, name: 'ResNet50' },
					],
				},
				{
					id: 5,
					name: 'BERT系列',
					children: [
						{ id: 6, name: 'BERT-base' },
						{ id: 7, name: 'BERT-large' },
						{ id: 8, name: 'RoBERTa' },
					],
				},
			],
		},
		{
			component: 'datetime',
			label: '计划开始时间',
			field: 'startTime',
			span: 12,
			width: 100,
			attrs: {
				placeholder: '请选择开始时间',
				format: 'YYYY-MM-DD HH:mm:ss',
				valueFormat: 'YYYY-MM-DD HH:mm:ss',
				clearable: true,
			},
		},
		{
			component: 'datetime',
			label: '计划结束时间',
			field: 'endTime',
			span: 12,
			width: 100,
			attrs: {
				placeholder: '请选择结束时间',
				format: 'YYYY-MM-DD HH:mm:ss',
				valueFormat: 'YYYY-MM-DD HH:mm:ss',
				clearable: true,
			},
		},
		{
			component: 'tag',
			label: '标签',
			field: 'tags',
			span: 24,
			width: 100,
			attrs: {
				placeholder: '请输入标签',
				collapseTags: true,
				collapseTagsTooltip: true,
			},
			options: [
				{ label: '深度学习', value: 'deep-learning' },
				{ label: '机器学习', value: 'machine-learning' },
				{ label: '神经网络', value: 'neural-network' },
				{ label: '人工智能', value: 'ai' },
			],
		},
		{
			component: 'color',
			label: '标记颜色',
			field: 'color',
			span: 12,
			width: 100,
			attrs: {
				showAlpha: true,
				colorFormat: 'hex',
			},
		},
		{
			component: 'upload',
			label: '数据集上传',
			field: 'datasetUpload',
			span: 24,
			width: 100,
			attrs: {
				action: '/api/system/sys-file/dataupload',
				multiple: true,
				accept: '.csv,.txt,.json,.png,.jpg,.jpeg',
				limit: 5,
				tip: '支持上传CSV、TXT、JSON、PNG、JPG、JPEG格式文件,单个文件不超过50MB',
				headers: {
					Authorization: `Bearer {Session.getToken()}`, // 将这里的yourAuthTokenHere替换为实际的令牌变量
				},
			},
		},
		{
			component: 'switch',
			label: '自动停止',
			field: 'autoStop',
			span: 13,
			width: 100,
			afterSlotName: 'switchRef', // 插槽可以插到表单后面
			attrs: {
				activeText: '是',
				inactiveText: '否',
				inlinePrompt: true,
			},
		},
		{
			component: 'radio',
			label: '',
			field: 'env',
			span: 13,
			width: 100,
			afterSlotName: 'radioRef',
			attrs: {
				border: true,
				size: 'large',
			},
			options: [
				{ label: '1小时', value: '1' },
				{ label: '2小时', value: '2' },
				{ label: '3小时', value: '3' },
				{ label: '4小时', value: '4' },
				{ label: '6小时', value: '6' },
				{ label: '自定义', value: '0' },
			],
		},
		{
			component: 'radio',
			label: '算法框架',
			field: 'algorithmFramework',
			span: 13,
			width: 100,
			attrs: {
				children: {
					border: true,
				},
			},
			options: [],
		},
		{
			component: 'radio',
			label: '数据类型',
			field: 'dataType',
			span: 13,
			width: 100,
			attrs: {
				label: 'name',
				value: 'id',
				children: {
					border: true,
				},
			},
			options: datasetData,
		},
		{
			component: 'select',
			label: '数据集',
			field: 'datasetKey',
			span: 13,
			width: 100,
			attrs: {
				placeholder: '请选择数据集',
				clearable: true,
				label: 'name',
				value: 'id',
			},
			options: datasetData,
		},
		{
			SlotName: 'select',
		},
	],
	rules: {
		name: [
			{ required: true, message: '请输入任务名称', trigger: 'blur' },
			{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' },
		],
		type: [{ required: true, message: '请选择模型类型', trigger: 'change' }],
		env: [{ required: true, message: '请选择运行环境', trigger: 'change' }],
		epochs: [
			{ required: true, message: '请输入训练轮次', trigger: 'blur' },
			{ type: 'number', min: 1, max: 1000, message: '轮次范围在 1 到 1000 之间', trigger: 'blur' },
		],
		batchSize: [
			{ required: true, message: '请输入批次大小', trigger: 'blur' },
			{ type: 'number', min: 1, max: 512, message: '批次大小范围在 1 到 512 之间', trigger: 'blur' },
		],
		learningRate: [{ required: true, message: '请设置学习率', trigger: 'blur' }],
		optimizer: [{ required: true, message: '请选择优化器', trigger: 'change' }],
		lossFunction: [{ required: true, message: '请选择损失函数', trigger: 'change' }],
		algorithmId: [{ required: true, message: '请选择算法', trigger: 'change' }],
	},
	model: {
		isPrefab: '1',
		algorithmId: '',
		algorithmVersionId: '',
		inType: '2',
		env: 'cpu',
	},
	labelWidth: '120px',
	size: 'default',
	gutter: 20,
});
const onSubmit = async () => {
	try {
		await wang_one.value.visible();
		// 校验通过后直接根据自己的业务提交
		console.log(form.model);
	} catch {
	} finally {
	}
};
const onCancel = () => {
	// router.back();
};
</script>