vue element封裝form表單的實(shí)現(xiàn)
一、新建FormComponent.vue
1.梳理思路,form表單有各種類型,常見(jiàn)的有input、select,radio,checkbox,time,date,date-picker,textarea,rate等
<template>
? <el-form ref="form" :model="formData" label-width="80px">
? ? <el-form-item
? ? ? v-for="item in formList"
? ? ? :key="item.prop"
? ? ? :label="item.label"
? ? ? :prop="item.prop"
? ? >
? ? ? <div class="form-item-container">
? ? ? ? <template v-if="item.prefix">
? ? ? ? ? <span class="prefix">{{ item.prefix }}</span> ?--前置單位
? ? ? ? </template>
? ? ? ? <template v-if="item.type === 'input'">
? ? ? ? ? <el-input
? ? ? ? ? ? v-model="formData[item.prop]"
? ? ? ? ? ? :placeholder="item.placeholder"
? ? ? ? ? ? :clearable="item.clearable"
? ? ? ? ? ? :maxlength="item.maxlength"
? ? ? ? ? ? @change="handleChange(item.prop, formData[item.prop])"
? ? ? ? ? />
? ? ? ? </template>
? ? ? ? <template v-if="item.type === 'textarea'">
? ? ? ? ? <el-input
? ? ? ? ? ? type="textarea"
? ? ? ? ? ? v-model="formData[item.prop]"
? ? ? ? ? ? :placeholder="item.placeholder"
? ? ? ? ? ? :clearable="item.clearable"
? ? ? ? ? ? :maxlength="item.maxlength"
? ? ? ? ? ? @change="handleChange(item.prop, formData[item.prop])"
? ? ? ? ? />
? ? ? ? </template>
? ? ? ? <template v-if="item.type === 'select'">
? ? ? ? ? <el-select
? ? ? ? ? ? v-model="formData[item.prop]"
? ? ? ? ? ? :placeholder="item.placeholder"
? ? ? ? ? ? :clearable="item.clearable"
? ? ? ? ? ? @change="handleChange(item.prop, formData[item.prop])"
? ? ? ? ? >
? ? ? ? ? ? <el-option
? ? ? ? ? ? ? v-for="option in item.options"
? ? ? ? ? ? ? :key="option.value"
? ? ? ? ? ? ? :label="option.label"
? ? ? ? ? ? ? :value="option.value"
? ? ? ? ? ? />
? ? ? ? ? </el-select>
? ? ? ? </template>
? ? ? ? <!-- 其它表單項(xiàng)同理 -->
? ? ? ? <template v-if="item.suffix">
? ? ? ? ? <span class="suffix">{{ item.suffix }}</span> ?--后置
? ? ? ? </template>
? ? ? </div>
? ? ? <div class="form-item-unit" v-if="item.unit">{{ item.unit }}</div> --單位
? ? </el-form-item>
? ? <div class="form-body" v-if="!$slots.default">
? ? ? <slot></slot>
? ? </div>
? ? <div class="form-footer" v-if="$slots.footer">
? ? ? <slot name="footer"></slot>
? ? </div>
? ? <div class="form-footer" v-else>
? ? ? <el-form-item>
? ? ? ? <el-button type="primary" @click="onSubmit" v-if="showSubmitButton">提交</el-button>
? ? ? ? <el-button @click="onCancel" v-if="showCancelButton">取消</el-button>
? ? ? </el-form-item>
? ? </div>
? </el-form>
</template>
<script>
export default {
? props: {
? ? formList: {
? ? ? type: Array,
? ? ? required: true,
? ? },
? ? formData: {
? ? ? type: Object,
? ? ? default: () => ({}),
? ? },
? ? actionUrl: {
? ? ? type: String,
? ? ? required: true,
? ? },
? ? showSubmitButton: {
? ? ? type: Boolean,
? ? ? default: true,
? ? },
? ? showCancelButton: {
? ? ? type: Boolean,
? ? ? default: true,
? ? },
? },
? methods: {
? ? handleChange(prop, value) {
? ? ? this.$emit('update:formData', {
? ? ? ? ...this.formData,
? ? ? ? [prop]: value,
? ? ? });
? ? },
? ? onSubmit() {
? ? ? this.$refs.form.validate((valid) => {
? ? ? ? if (valid) {
? ? ? ? ? this.$axios.post(this.actionUrl, this.formData).then((res) => {
? ? ? ? ? ? this.$emit('submit-success', res);//回調(diào)
? ? ? ? ? });
? ? ? ? } else {
? ? ? ? ? this.$message.error('請(qǐng)檢查表單是否填寫(xiě)正確');
? ? ? ? }
? ? ? });
? ? },
? ? onCancel() {
? ? ? this.$emit('cancel');
? ? },
? },
};
</script>
<style>
.form-item-container {
? position: relative;
? display: inline-block;
}
.prefix,
.suffix {
? position: absolute;
? top: 50%;
? transform: translateY(-50%);
? font-size: 14px;
}
.prefix {
? left: 8px;
}
.suffix {
? right: 8px;
}
.form-item-unit {
? display: inline-block;
? margin-left: 8px;
? color: #909399;
}
.form-body {
? margin-bottom: 20px;
? border: 1px solid #e4e7ed;
? border-radius: 4px;
? padding: 20px;
}
.form-footer {
? text-align: right;
? margin-top: 20px;
}
</style>二、如何使用
引入import formComponent from 'xx';
<template>
? <div>
? ? <form-component
? ? ? :form-list="formList"
? ? ? :form-data="formData"
? ? ? :action-url="actionUrl"
? ? ? :show-submit-button="true"
? ? ? :show-cancel-button="true"
? ? ? @submit-success="onSubmitSuccess"
? ? ? @cancel="onCustomCancel"
? ? ? >
? ? ? <!-- 自定義表單內(nèi)容 -->
? ? ? <template #default>
? ? ? ? <el-form-item>
? ? ? ? ? <el-radio-group v-model="formData.gender">
? ? ? ? ? ? <el-radio label="male">男性</el-radio>
? ? ? ? ? ? <el-radio label="female">女性</el-radio>
? ? ? ? ? </el-radio-group>
? ? ? ? </el-form-item>
? ? ? ? <el-form-item>
? ? ? ? ? <el-cascader
? ? ? ? ? ? v-model="formData.address"
? ? ? ? ? ? :options="addressOptions"
? ? ? ? ? ? placeholder="請(qǐng)選擇地址"
? ? ? ? ? ? @change="handleChange('address', formData['address'])"
? ? ? ? ? />
? ? ? ? </el-form-item>
? ? ? ? <el-form-item>
? ? ? ? ? <el-input
? ? ? ? ? ? v-model="formData.email"
? ? ? ? ? ? placeholder="請(qǐng)輸入電子郵箱"
? ? ? ? ? ? clearable
? ? ? ? ? ? @change="handleChange('email', formData['email'])"
? ? ? ? ? />
? ? ? ? </el-form-item>
? ? ? </template>
? ? ? <!-- 自定義底部按鈕,也可以不添加,使用默認(rèn)底部按鈕 -->
? ? ? <template #footer>
? ? ? ? <el-button type="primary" @click="onCustomSubmit">提交</el-button>
? ? ? ? <el-button @click="onCustomCancel">取消</el-button>
? ? ? </template>
? ? </form-component>
? </div>
</template>
<script>
import FormComponent from './FormComponent.vue';
export default {
? components: {
? ? FormComponent,
? },
? data() {
? ? return {
? ? ? formList: [
? ? ? ? {
? ? ? ? ? label: '姓名',
? ? ? ? ? prop: 'name',
? ? ? ? ? type: 'input',
? ? ? ? ? placeholder: '請(qǐng)輸入姓名',
? ? ? ? ? clearable: true,
? ? ? ? ? maxlength: 20,
? ? ? ? },
? ? ? ? {
? ? ? ? ? label: '性別',
? ? ? ? ? prop: 'gender',
? ? ? ? ? type: 'select',
? ? ? ? ? placeholder: '請(qǐng)選擇性別',
? ? ? ? ? clearable: true,
? ? ? ? ? options: [
? ? ? ? ? ? {
? ? ? ? ? ? ? label: '男性',
? ? ? ? ? ? ? value: 'male',
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? label: '女性',
? ? ? ? ? ? ? value: 'female',
? ? ? ? ? ? },
? ? ? ? ? ],
? ? ? ? },
? ? ? ? {
? ? ? ? ? label: '地址',
? ? ? ? ? prop: 'address',
? ? ? ? ? type: 'cascader',
? ? ? ? ? placeholder: '請(qǐng)選擇地址',
? ? ? ? ? clearable: true,
? ? ? ? ? options: [],
? ? ? ? },
? ? ? ? {
? ? ? ? ? label: '電子郵箱',
? ? ? ? ? prop: 'email',
? ? ? ? ? type: 'input',
? ? ? ? ? placeholder: '請(qǐng)輸入電子郵箱',
? ? ? ? ? clearable: true,
? ? ? ? ? maxlength: 50,
? ? ? ? },
? ? ? ],
? ? ? formData: {
? ? ? ? name: '',
? ? ? ? gender: '',
? ? ? ? address: [],
? ? ? ? email: '',
? ? ? },
? ? ? addressOptions: [
? ? ? ? {
? ? ? ? ? value: 'beijing',
? ? ? ? ? label: '北京',
? ? ? ? ? children: [
? ? ? ? ? ? {
? ? ? ? ? ? ? value: 'haidian',
? ? ? ? ? ? ? label: '海淀區(qū)',
? ? ? ? ? ? ? children: [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? value: 'zizhuqiao',
? ? ? ? ? ? ? ? ? label: '紫竹橋',
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? value: 'xizhimen',
? ? ? ? ? ? ? ? ? label: '西直門(mén)',
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ],
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? value: 'chaoyang',
? ? ? ? ? ? ? label: '朝陽(yáng)區(qū)',
? ? ? ? ? ? ? children: [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? value: 'guomao',
? ? ? ? ? ? ? ? ? label: '國(guó)貿(mào)',
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? value: 'cbd',
? ? ? ? ? ? ? ? ? label: 'CBD',
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ],
? ? ? ? ? ? },
? ? ? ? ? ],
? ? ? ? },
? ? ? ? {
? ? ? ? ? value: 'shanghai',
? ? ? ? ? label: '上海',
? ? ? ? ? children: [
? ? ? ? ? ? {
? ? ? ? ? ? ? value: 'xuhui',
? ? ? ? ? ? ? label: '徐匯區(qū)',
? ? ? ? ? ? ? children: [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? value: 'xujiahui',
? ? ? ? ? ? ? ? ? label: '徐家匯',
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ],
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? value: 'pudong',
? ? ? ? ? ? ? label: '浦東新區(qū)',
? ? ? ? ? ? ? children: [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? value: 'lujiazui',
? ? ? ? ? ? ? ? ? label: '陸家嘴',
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ],
? ? ? ? ? ? },
? ? ? ? ? ],
? ? ? ? },
? ? ? ],
? ? ? actionUrl: '/api/submit-form',
? ? };
? },
? methods: {
? ? onCustomSubmit() {
? ? ? // 自定義提交按鈕的點(diǎn)擊事件
? ? },
? ? onCustomCancel() {
? ? ? // 自定義取消按鈕的點(diǎn)擊事件
? ? },
? ? onSubmitSuccess(res) {
? ? ? // 表單提交成功的回調(diào)函數(shù)
? ? },
? },
};
</script>到此這篇關(guān)于vue element封裝form表單的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)vue element封裝form表單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue ElementUI之Form表單驗(yàn)證遇到的問(wèn)題
- vue+elementUI實(shí)現(xiàn)表單和圖片上傳及驗(yàn)證功能示例
- vue用elementui寫(xiě)form表單時(shí),在label里添加空格操作
- vue中使用element-ui進(jìn)行表單驗(yàn)證的實(shí)例代碼
- vue+Element-ui實(shí)現(xiàn)登錄注冊(cè)表單
- vue elementui form表單驗(yàn)證的實(shí)現(xiàn)
- 解決vue+ element ui 表單驗(yàn)證有值但驗(yàn)證失敗問(wèn)題
- vue+element創(chuàng)建動(dòng)態(tài)的form表單及動(dòng)態(tài)生成表格的行和列
- Vue+Element實(shí)現(xiàn)動(dòng)態(tài)生成新表單并添加驗(yàn)證功能
相關(guān)文章
vue中input type=file上傳后@change事件無(wú)效的解決方案
這篇文章主要介紹了vue中input type=file上傳后@change事件無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
詳解在vue使用weixin-js-sdk常見(jiàn)使用方法
這篇文章主要介紹了 詳解在vue使用weixin-js-sdk常見(jiàn)使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
vue 綁定使用 touchstart touchmove touchend解析
這篇文章主要介紹了vue 綁定使用 touchstart touchmove touchend解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Vue.js實(shí)戰(zhàn)之組件之間的數(shù)據(jù)傳遞
這篇文章主要介紹了Vue.js實(shí)戰(zhàn)之組件之間的數(shù)據(jù)傳遞的相關(guān)資料,文中通過(guò)示例代碼和圖文介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-04-04

