1.0.0 • Published 9 months ago
vue-zoey-form v1.0.0
VueZoeyForm 组件
VueZoeyForm 是一个用于生成表单的 Vue 组件。基于elementUI,它提供了各种不同类型的表单字段,包括文本输入框、多行文本框、密码框、下拉框、单选框、开关、多选框、日期选择器、时间选择器、图片上传、按钮等。你可以根据具体需求配置不同的字段和验证规则。
下载并且调用
npm install --save vue-zoey-form
// main.js
import VueZoeyForm from 'vue-zoey-form'
Vue.use(VueZoeyForm)
Props参数
config
(required): 表单的配置对象,包含以下属性:title
(String): 表单标题(可选)。cards
/items
(Array): 表单项数组,有/无 边框阴影独立每块内容,每个项包含以下属性:label
(String): 字段描述,比如‘用户名’,‘密码’type
(String): 字段类型,比如‘text’,‘password’key
(String): 字段的键,提交给后端的字段,比如username,passwordvalue
(Any): 字段的初始值。attrs
(Object): 字段的额外属性(可选),主要是原本elementui的原始属性,用于传递给对应的表单组件。options
(Array): 对于下拉框和单选框类型的字段,选项数组,每个选项包含value
和label
属性。colspan
(number): 列,比如一行一列,一行2列
事件
submit
: 当表单验证通过并提交时触发该事件,并传递表单数据对象作为参数。reset
: 重置表单数据
插槽
btn
: 用于自定义按钮组件的插槽。可以接收一个含有参数t
和ruleForm
的函数,其中t
是按钮文本,ruleForm
是表单数据对象。如果未提供该插槽,则默认显示提交和重置按钮。
字段类型
VueZoeyForm 组件支持的字段类型及其对应的取值为:
text
: 文本输入框textarea
: 多行文本框password
: 密码框select
: 下拉框radio
: 单选框switchs
: Switch 开关checkbox
: 多选框datepicker
: 日期选择器timepicker
: 时间选择器timeselect
: 时间点选择器images
: 图片上传button
: 按钮custom
: 自定义模版
使用示例
<template>
<div>
<VueZoeyForm ref="form" :config="formConfig" @submit="handleSubmit"> </VueZoeyForm>
</div>
</template>
<script>
import formConfig from './page';
export default {
methods: {
handleSubmit(formData) {
// 处理表单提交逻辑
console.log('表单数据:', formData)
},
handlereset(){
this.$refs.form.reset()
}
},
}
</script>
数据如下:
没有边框版本
// page.js
const TEXTAREA = 'textarea' // 多行文本
const PASSWORD = 'password' // 密码
const RADIO = 'radio' // 单选框
const DATE_PICKER = 'datepicker' // 日期选择器
// 性别
export const sexOptions = [{
value: 'man',
label: '男'
},
{
value: 'woman',
label: '女'
}
]
// 婚否
export const marriageOptions = [{
value: 'married',
label: '已婚'
},
{
value: 'unmarried',
label: '未婚'
}
]
// 优化 => data方法中,默认是会Object.defineProperty => 当触发属性的get/set => 页面的更新
export default {
items: Object.freeze([
[{
label: '用户名',
colspan: 24,
key: 'account',
type: TEXTAREA
}],
[{
label: '密码',
colspan: 24,
key: 'password',
type: PASSWORD
}],
[{
label: '确认密码',
colspan: 24,
key: 'confirmPwd',
type: PASSWORD
}],
[{
label: '性别',
colspan: 8,
key: 'sex',
type: RADIO,
value: 'man',
options: sexOptions
}],
[{
label: '出生日期',
key: 'dd',
type: DATE_PICKER,
colspan: 8,
attrs: {
type: 'date',
'placeholder': '选择日期'
}
}, ],
[{
label: '性别',
colspan: 8,
key: 'sex',
type: RADIO,
value: 'unmarried',
options: marriageOptions
}]
]),
rules: {
account: [{
"required": true,
"message": "用户名必填",
"trigger": "blur"
}],
password: [{
"required": true,
"message": "用户名必填",
"trigger": "blur"
},
{
"trigger": "blur",
message: '密码必须要6-12位之间',
min: 6,
max: 12,
}
],
confirmPwd: [{
"trigger": "blur",
validator: function (rule, value, callback) {
if (!value) {
return callback(new Error('确认密码不能为空'));
}
if (value === this.formData.password) {
return callback();
} else {
return callback(new Error('两次密码不一致..'))
}
}
}],
}
}
cards版本 有边框
// page.js
const TEXTAREA = 'textarea'// 多行文本
const PASSWORD = 'password' // 密码
const RADIO = 'radio'// 单选框
const SWITCH = 'switchs'// Switch 开关
const DATE_PICKER = 'datepicker'// 日期选择器
const TIME_PICKER = 'timepicker'// 时间选择器
// 性别
export const sexOptions = [
{ value: 'man', label: '男' },
{ value: 'woman', label: '女' }
]
// 婚否
export const marriageOptions = [
{ value: 'married', label: '已婚' },
{ value: 'unmarried', label: '未婚' }
]
// 优化 => data方法中,默认是会Object.defineProperty => 当触发属性的get/set => 页面的更新
export default Object.freeze({
cards: [
{
// name: '测试信息',
children: [
[
{ label: '出生日期', key: 'dd', type: DATE_PICKER,
attrs: { type: 'date', 'placeholder': '选择日期' }
},
{ label: '准确时间', key: 'birthtime', type: TIME_PICKER,
attrs: { 'placeholder': '任意时间点', 'value-format': 'timestamp' }
},
{ label: '时间段', key: 'birthtimes', type: TIME_PICKER,
attrs: {
'is-range': true, 'start-placeholder': '开始时间',
'end-placeholder': '结束时间',
'range-separator': '至', 'arrow-control': true, 'value-format': 'timestamp'
}
},
{
label: '日历',
key: 'leadar',
type: SWITCH,
attrs: {
'active-color': 'red',
'active-text': '阳历', 'inactive-text': '农历'
}
},
{
label: '性别',
key: 'sex',
type: RADIO,
value: 'man',
options: sexOptions
}
],
[{ label: '身份证', key: 'identity_card', type: PASSWORD }],
[
{
label: '婚姻状态',
key: 'marriage',
type: RADIO,
options: marriageOptions
},
{ label: '居住地址', key: 'address1', type: TEXTAREA }
]
].map(row => row.map(item => ({ colspan: 8, ...item })))
},
],
rules: {
identity_card: [
{ required: true, message: '请输入身份证', trigger: 'change' }
],
}
}
)
在以上示例中,我们定义了一个包含多个表单字段的表单配置对象 formConfig
,其中使用了不同的字段类型和相应的属性。在 <vue-zoey-form>
组件中,我们绑定了 config
属性为 formConfig
,并监听了 submit
事件,在事件处理函数中可获取到表单数据对象。当然也可以使用自定义按钮插槽 btn
,将按钮的点击事件绑定到 submitForm
方法。
只需根据需要配置 config
属性,定义自己的表单字段和验证规则,并监听 submit
事件处理表单提交的逻辑。
每个类型展示
<template>
<div>
<VueZoeyForm :config="conf" @submit="createLoan">
<template #imagesTemplate="{ }">
<el-upload
class="avatar-uploader"
list-type="picture-card"
:show-file-list="false"
action="https://jsonplaceholder.typicode.com/posts/"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon" />
</el-upload>
</template>
<template #customTemplate="{ }">
<el-input v-model="input" placeholder="请输入内容" style="width:100px" />
<el-select v-model="value" placeholder="请选择">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-button type="primary">主要按钮</el-button>
</template>
<template #btn="{ t,ruleForm }">
<el-button @click="createLoan(ruleForm)">提交{{ t }}</el-button>
</template>
</VueZoeyForm>
</div>
</template>
<script>
import conf from './pagelist'
export default {
name: 'PageZoey',
data() {
return {
conf, input: '', imageUrl: '',
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}],
value: ''
}
},
beforeDestroy() {
console.log(this.$options.name, '被销毁了..')
},
methods: {
async createLoan(user) {
console.log(user)
this.$notify.success('添加成功')
},
}
}
</script>
数据如下
// pagelist.js
const TEXT = 'text'// 文本
const TEXTAREA = 'textarea'// 多行文本
const PASSWORD = 'password' // 密码
const SELECT = 'select' // 下拉框
const RADIO = 'radio'// 单选框
const SWITCH = 'switchs'// Switch 开关
const CHECKBOX = 'checkbox'// 多选框
const DATE_PICKER = 'datepicker'// 日期选择器
const TIME_PICKER = 'timepicker'// 时间选择器
const TIME_SELECT = 'timeselect'// 时间点选择器
const CUSTOM = 'custom' // 自定义模版
const IMAGES = 'images'// 图片上传
const BUTTON = 'button' // 按钮
// 性别
export const sexOptions = [
{ value: 'man', label: '男' },
{ value: 'woman', label: '女' }
]
// 行业
export const companyOptions = [
{ value: 'education', label: '教育' },
{ value: 'finance', label: '金融' }
]
// 区域
export const cityOptions = [
{ value: 'sh', label: '上海' },
{ value: 'bj', label: '北京' },
{ value: 'gz', label: '广州' },
{ value: 'sz', label: '深圳' }
]
// 婚否
export const marriageOptions = [
{ value: 'married', label: '已婚' },
{ value: 'unmarried', label: '未婚' }
]
// 学历
export const educationOptions = [
{ value: 'college', label: '大学' },
{ value: 'highschool', label: '高中' },
{ value: 'chuz', label: '初中' },
{ value: 'xiaox', label: '小学' }
]
// 优化 => data方法中,默认是会Object.defineProperty => 当触发属性的get/set => 页面的更新
export default Object.freeze({
cards: [
{
name: '个人基本信息',
children: [
[
{ label: '姓名', key: 'name', type: TEXT },
{ label: '出生日期', key: 'birthday', type: DATE_PICKER,
attrs: { type: 'date', 'placeholder': '选择日期' }
},
{ label: '准确时间', key: 'birthtime', type: TIME_PICKER,
attrs: { 'placeholder': '任意时间点', 'value-format': 'timestamp' }
},
{ label: '时间段', key: 'birthtimes', type: TIME_PICKER,
attrs: {
'is-range': true, 'start-placeholder': '开始时间',
'end-placeholder': '结束时间',
'range-separator': '至', 'arrow-control': true, 'value-format': 'timestamp'
}
},
{
label: '日历',
key: 'leadar',
type: SWITCH,
attrs: {
'active-color': 'red',
'active-text': '阳历', 'inactive-text': '农历'
}
},
{
label: '性别',
key: 'sex',
type: RADIO,
value: 'man',
options: sexOptions
}
],
[{ label: '身份证', key: 'identity_card', type: PASSWORD }],
[
{
label: '婚姻状态',
key: 'marriage',
type: RADIO,
options: marriageOptions
},
{
label: '教育程度',
type: SELECT,
key: 'education',
options: educationOptions
// optionsList: [{ key: 'education', list: educationOptions }, { key: 'education1', list: marriageOptions }, { key: 'education2', list: educationOptions }]
},
{ label: '就学时间', key: 'study', type: DATE_PICKER,
attrs: {
type: 'daterange',
'range-separator': '至',
'start-placeholder': '开始日期',
'value-format': 'yyyy-MM-dd',
'end-placeholder': '结束日期'
}
},
{ label: '居住地址', key: 'address1', type: TEXTAREA }
]
// [
// { label: '户籍地址', key: 'address2', type: TEXT },
// { label: '居住电话', key: 'phone', type: TEXT },
// { label: '手机号', key: 'mobile_phone', type: TEXT }
// ]
].map(row => row.map(item => ({ colspan: 8, ...item })))
},
{
name: '职业信息',
children: [
[ // element原生属性
{ label: '选择信息', btn: '选择', key: '', type: BUTTON,
action: function actions() {
console.log(1111)
},
attrs: {
'type': 'warning', 'round': true
}
},
{ label: '选择头像', key: 'icon', type: IMAGES },
{ label: '自定义模版', key: 'suc', type: CUSTOM, attr: { 'label-width': '100px' }},
{ label: '现职公司', key: 'company', type: TEXT },
{ label: '工作时间', key: 'worktime', type: TIME_SELECT,
attrs: { 'placeholder': '任意时间点' }
},
{
label: '所属区域',
attrs: { placeholder: '请选择' },
key: 'position', type: CHECKBOX,
options: cityOptions
},
{
label: '所属行业',
attrs: { placeholder: '请选择' },
key: 'trade', type: RADIO,
options: companyOptions
}
].map(item => ({ colspan: 12, ...item }))
]
}
],
rules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
{
min: 2,
max: 5,
message: '长度在 2 到 5 个字符',
trigger: 'blur'
}
],
identity_card: [
{ required: true, message: '请输入身份证', trigger: 'change' }
],
birthday: [
{
required: true,
message: '请选择日期',
trigger: 'change'
}
],
study: [
{
required: true,
message: '请选择时间段',
trigger: 'change'
}
],
sex: [{ required: true, message: '请选择性别', trigger: 'change' }],
marriage: [
{ required: true, message: '请选择婚姻状态', trigger: 'change' }
],
education: [
{ required: true, message: '请选择教育程度', trigger: 'change' }
],
trade: [
{ required: true, message: '请选择所属行业', trigger: 'change' }
],
position: [
{ required: true, message: '请选择所属区域', trigger: 'change' }
]
}
}
)
开发上传步骤
安装并配置发布相关的依赖项
npm install --save-dev rimraf
在package.json文件中添加构建和发布脚本
{
"name": "vue-zoey-form",
"version": "1.0.0",
"main": " dist/vue-zoey-form.umd.min.js ",
"keywords": ["vue", "zoey", "form"],
"author": "zoey",
"license": "MIT",
"scripts": {
"build": "rimraf dist && vue-cli-service build --target lib --name vue-zoey-form src/components/VueZoeyForm.vue",
"prepublishOnly": "npm run build"
}
}
步骤
- 使用了rimraf工具来在构建之前删除dist文件夹。
- 使用vue-cli-service将 VueZoeyForm.vue构建为一个名为vue-zoey-form.js的库文件
- 运行以下命令将组件发布到npm
npm config get registry
npm config set registry https://registry.npmjs.org/ # 检查注册表并且更换为官网注册表
npm login # 按照提示输入用户名、密码和电子邮件地址以登录到npm账户
// npm login
// npm notice Log in on https://registry.npmjs.org/
// Username: zoeyz0000
// Password:
// Email: (this IS public) 1291609705@qq.com
// npm notice Please check your email for a one-time password (OTP)
// Enter one-time password: 12417992
// Logged in as zoeyz0000 on https://registry.npmjs.org/.
打包dist yarn build
运行发布命令
npm publish # 将组件上传到npm仓库中
# 不允许私有包。所以需要package.json "private": false,
- 删除
npm unpublish <package-name> [--force] // <package-name> 替换为您要删除的包的名称 --force 标志以强制删除
// npm unpublish xxx --force