vue如何封装form表单组件拒绝重复写form表单
本篇内容主要讲解“vue如何封装form表单组件拒绝重复写form表单”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue如何封装form表单组件拒绝重复写form表单”吧!
核心思想:
通过配置
js
文件的变量,使用vue
的is
属性动态切换组件,默认显示的组件为el-input
通过
element
的分栏和栅格属性,对form
表单进行响应式布局baseForm
在组件初始化时,需要动态添加校验规则
、请求接口
以及初始化form
的部分值正统思想是对
element
组件的各个组件进行二次封装,form表单封装,然后通过is
属性切换二次封装后的组件,在此不做过多思路描述,vueelement表单封装,vue如何封装form表单组件拒绝重复写form表单,有兴趣的朋友可以自行研究更好的思想是将页面请求、搜索项、表格、分页封装到一起,形成一个整体,这也是我们前端小组目前的处理思路
实现重点:
任何标签或者组件vue都可以通过
vue的is
属性来动态切换组件。本组件中使用div
,将它的宽度设置为100%
,使得element
组件能够组件完全撑开。(使用vue内置组件component会与el-radio-group
相冲突,vue如何封装一个form表单,因为它函数底层就是用component
实现的)表单上添加
validate-on-rule-change="false"
属性拒绝,防止在表单初始化时就校验表单当为对象取添加不存在的字段属性时,需要使用
$set
实现数据的响应式如果
form
表单过程中只有一个输入框,vue怎么接收form参数,在vueelement输入框中按下回车会提交表单,刷新页面。为了阻止这一默认行为,需要在el-form
标签上添加@submit.native.prevent
使用
lodash
中的get
方法获取对象的属性值,如果属性值不存在,可以给一个默认值baseForm
子组件中可以传一个form
对象给父组件装的,那么添加或者编辑原理form
对象,就都可以在父组件中进行。
表单双向绑定的方式有两种:
1.使用v-model进行双向绑定
<div v-else clearable type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" v-model="form[column.prop]" :label-width="get(column,vue怎么封装函数, 'size', column || defaultFormSize)" :disabled="get(column, 'disabled', false)" :is="get(column, 'type', 'el-input')" >
2.vue使用装的v-model的语法取糖
(`:value以及@表单input`)进行双向绑定
<div v-表格else clearable type="daterange" range-separator="至" start-placeholder="开始组件日期获取" end-placeholder="结束日期" :value="form[column.prop]" :label-width="get(column, 'size', column || defaultFormSize)" :disabled="get(column, 'disabled', false)" :is="get(column, 'type', 'el-input')" @input="input($event,column.prop)" > methods: { input(e,prop) { this.$set(this.form, prop, e) } }
配置项
(本组过程件写得比较基础,目前仅支持element的五个常用组件):
整体字段:
formSize
(表单封装中各表格element组件的整体大小)
column数组中每一个对象对应的字段(非请求接口):
label
(表单label的名称)span
(这个表单项占据的份数,一行为24
,默认为12
)labelWidth
(这个表单项的label宽度
,默认为90px
)labelHeight
(这个表单项占据的高度,默认为50px
)slotName
(插槽名)prop
(这个表单项绑定的属性名称)size
(这个表单项组件的原理大小过程,默认为small
)disabled
(是否禁用这个表单项)type
(使用的element
组件,vue组件怎么使用自己封装的方法,默认为el-input
)dic
(非函数接口请求的静态表单数据,vue表单封装,使用{label以及value字段}
表示接收的数组形式接收)
column数组中每一个对象对应方法的字段(请求复写接口):
url
(接口的api
地址)requestParams
(非必填项,需要额外传入的传参)requestLabel
(接口返回重复对应的id
)requestValue
(接口返回重复对应的value
)
效果浏览
源码放送
1. baseForm组件
<template> <el-form ref="form" :model="form" :rules="formRules" :size="get(option, 'formSize', defaultFormSize)" :validate-on-rule-change="false" @submit.native.prevent > <el-row :gutter="20" :span="24"> <el-col v-for="column in formColumn" :key="column.label" :md="column.span || 12" :sm="12" :xs="24" > <el-form-item :label="`${column.label}:`" :prop="column.prop" :label-width="get(column, 'labelWidth', column.labelWidth || defaultLabelWidth)" :style="{ height: get(column, 'labelHeight', column.labelHeight || defaultLabelHeight) }" > <slot v-if="column.slotName" :name="column.slotName" :form="form" :prop="column.prop" :value="form[column.prop]" ></slot> <div v-else clearable type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" v-model="form[column.prop]" :placeholder="getPlaceholder(column.type, column.label)" :label-width="get(column, 'size', column || defaultFormSize)" :disabled="get(column, 'disabled', false)" :is="get(column, 'type', 'el-input')" > <template v-if="column.type == 'el-select'"> <el-option v-for="item in column.dic" :key="item.value" :label="item.label" :value="item.value" > </el-option> </template> <template v-if="column.type == 'el-radio-group'"> <el-radio v-for="item in column.dic" :key="item.value" :label="item.label" > {{ item.value }} </el-radio> </template> <template v-if="column.type == 'el-checkbox-group'"> <el-checkbox v-for="item in column.dic" :key="item.label" :label="item.value" > {{ item.label }} </el-checkbox> </template> </div> </el-form-item> </el-col> </el-row> </el-form> </template> <script> import get from 'lodash/get' import request from '@/service/request' export default { props: { option: { type: Object, default: () => {} }, form: { type: Object, default: () => {} } }, data() { return { formRules: {}, defaultFormSize: 'small', defaultLabelWidth: '90px', defaultLabelHeight: '50px' } }, computed: { formColumn() { return this.option.column } }, created() { this.initRules() this.initRequest() this.initValue() }, methods: { get, getPlaceholder(type, label) { return type == 'el-select' ? `请选择${label}` : `请输入vueelement${label}` }, initRequest() { if (!Array.isArray(this.formColumn)) return // 根据实际请求接口地址的前缀来判断 const urls = this.formColumn?.filter((item) => item.url && item.url.indexOf('/emes') == 0) || [] urls.forEach(async (item) => { const data = { page: { pageIndex: 1, pageSize: 0 }, ...item.requestParams } const { detail } = await request({ url: item.url, method: 'post', data }) || [] const finalResult = detail.map((result) => ({ label: result[item.requestLabel], value: result[item.requestValue] })) this.$set(item, 'dic', finalResult) }) }, initRules() { if (!Array.isArray(this.formColumn)) return this.formColumn?.forEach((item) => { if (item.rules) { item.rules.map((rule, index) => { if (rule.required) { item.rules.splice(index, 1, { message: ['el-radio-group', 'el-checkbox-group'].includes(item.type) ? `${item.label}必选` : `${item.label}必填`, ...rule }) } }) this.$set(this.formRules, item.prop, item.rules) } }) }, initValue() { const selectList = this.formColumn.filter((item) => ['el-radio-group', 'el-checkbox-group'].includes(item.type)) selectList.forEach((item) => { this.$set(this.form, item.prop, item.type == 'el-radio-group' ? item.dic[0].label : [item.dic[0].value]) }) } } } </script>
2. 父组件
<template> <div class="app-container"> <myForm :option="option" :form="form"> <template #usageSlot="{form, prop}"> <el-input size="small" placeholder="请输入插槽使用" v-model="form[prop]" clearable > </el-input> </template> </myForm> </div> </template> <script> import { option } from './const.js' export default { data() { return { option, form: {} } } } </script>
3. 配置项
export const option = { column: [ { label: '姓名', prop: 'name', span: 8, rules: [ { required: true } ] }, { label: '职业', prop: 'job', type: 'el-select', span: 8, dic: [ { label: '教师', value: 0 }, { label: '程序猿', value: 1 }, { label: '作家', value: 2 } ], rules: [ { required: true } ] }, { label: '性别', prop: 'sex', span: 8, type: 'el-radio-group', dic: [ { label: 0, value: '男' }, { label: 1, value: '女' } ], rules: [ { required: true } ] }, { label: '城市', prop: 'city', type: 'el-checkbox-group', span: 8, dic: [ { label: '仙桃', value: 0 }, { label: '泉州', value: 1 }, { label: '武汉', value: 2 } ], rules: [ { required: true } ] }, { label: '出生日期', prop: 'data', type: 'el-date-picker', span: 8, rules: [ { required: true } ] }, { label: '测试', prop: 'test', type: 'el-select', span: 8, url:'/emes/factoryOrderService/warehouse/list', requestLabel: 'warehouseName', requestValue: 'id', rules: [ { required: true } ] }, { label: '插槽使用', prop: 'usage', slotName: 'usageSlot', span: 8, rules: [ { required: true } ] } ] }
4. 添加或编辑
添加: 如果是添加状态,直接在父组件中引入就好。在点击确定按钮时,拿到子组件的
ref
并进行表单校验。校验通过思路vue3后,使用后端定义好的接口进行传参;编辑: 如果是编辑状态,则需要在父组件页面初始化时,将后端返回的数据使用
$set
进行初始赋值,其余操作同添加状态,vue 表单封装。
到此,相信大家对“vue如何封装form表单组件拒绝重复写form表单”有了更深的了解,不妨来实际操作封装一番吧!这里是重复蜗牛博客网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系原理站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容,vue form 组件封装。
评论