您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何在vue中使用elementUI上傳表單和圖片,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
Vue具體輕量級框架、簡單易學、雙向數據綁定、組件化、數據和結構的分離、虛擬DOM、運行速度快等優勢,Vue中頁面使用的是局部刷新,不用每次跳轉頁面都要請求所有數據和dom,可以大大提升訪問速度和用戶體驗。
1、表單內容的驗證及必填項
2、新增和編輯用同一個組件如何處理數據
3、圖片需要和信息一起傳遞(即不允許自動上傳)
4、圖片必填的驗證問題
針對上述問題作出方案:
1、el-form的表單驗證需要注意幾個地方:
a:el-form-item的prop值需要和表單標簽的v-model值保持一致
例如:
<el-form-item label="姓名:" prop="name"> <el-input v-model="addKeyPersonForm.name" placeholder="請輸入姓名"></el-input> </el-form-item>
b:驗證規則有直接用element官網提供的也有自定義的
例如:其中checkNumber就是自定義的驗證數字的正則
rules: { // 表單驗證 name: [ { required: true, message: '必填項', trigger: 'blur' } ], age: [ { required: true, message: '必填項', trigger: 'blur' }, { validator: checkNumber, trigger: 'blur' } ], sex: [ { required: true, message: '必填項', trigger: ['blur', 'change'] } ], nationlity: [ { required: true, message: '必填項', trigger: ['blur', 'change'] } ], userType: [ { required: true, message: '必填項', trigger: ['blur', 'change'] } ], idCard: [ { required: true, message: '必填項', trigger: 'blur' }, { validator: checkIdCard, trigger: 'blur' } ], registered: [ { required: true, type: 'array', message: '必填項', trigger: ['blur', 'change'] } ], registeredDetails: [ { required: true, message: '必填項', trigger: 'blur' } ], domicile: [ { required: true, type: 'array', message: '必填項', trigger: ['blur', 'change'] } ], domicileDetails: [ { required: true, message: '必填項', trigger: 'blur' } ], file: [ { required: true, message: '請上傳圖片' } ], plateNumber: [ { validator: checkPlateNum, trigger: 'change' } ] }
2、新增和編輯問題需要我們在打開組件的時候傳遞兩個值
props: { dialogType: { //是新增還是編輯,用于判斷 type: String }, keypersonList: { //表單的原始值 type: Object } }
3、圖片和form表單內容一起上傳
首先我們需要阻止圖片的自動上傳讓它等到我們點擊保存按鈕的時候再一起傳給后臺
我們看這段代碼就是圖片上傳組件
<el-upload class="upload-img" : ref="uploadxls" action="aaa" ::limit="1" :show-file-list="false" :on-change="handlePictureCardPreview" :before-upload="beforeupload" accept="image/png,image/gif,image/jpg,image/jpeg"> <i v-show="!dialogImageUrl" class="el-icon-upload avatar-uploader-icon"></i> <div v-show="!dialogImageUrl" slot="tip" class="el-upload__text upload__tip">上傳照片</div> </el-upload>
action我們隨便填一個就好,重點是這一句:before-upload="beforeupload"在圖片上傳之前執行beforeupload方法在里面return false就可以實現阻止upload自動上傳
// 阻止upload的自己上傳,進行再操作 beforeupload (file) { this.formData.append('file', file) return false }
關于圖片和表單文件一起上傳我們選擇了formData格式存儲數據用于上傳
選擇了圖片并填寫必填信息之后點擊保存進行上傳操作,在onSubmit方法里把表單信息都append到formData里that.$refs.uploadxls.submit() // 提交時觸發了before-upload函數--》完成圖片的上傳即執行beforeupload方法
4、圖片必填的驗證問題:
a、如果沒有選擇圖片點擊保存則圖片提示:請上傳圖片
b、此時選擇了圖片則“請上傳圖片”消失
驗證規則里有一條file就是做圖片必填驗證的
file: [ { required: true, message: '請上傳圖片' } ]
c、在編輯重點人員信息時重點人員圖片已存在沒有進行圖片上傳操作此時點擊保存應該不提示“請上傳圖片”,未解決這個問題我們在上傳時添加判斷:
如果是編輯信息且未進行過圖片上傳操作則去掉file驗證
就是以下代碼
that.rules.file = [{ required: true, message: '請上傳圖片' }] if (that.dialogType !== 'add' && !this.doUpload) { that.rules.file = [] that.$refs['uploadElement'].clearValidate() }
整個彈框組件的代碼如下:
<template> <div class="add-keyperson-dialog"> <el-form :inline="true" ref="addKeyPersonForm" :model="addKeyPersonForm" class="demo-form-inline" label-width="1.4rem" :rules="rules"> <el-form-item label="姓名:" prop="name"> <el-input v-model="addKeyPersonForm.name" placeholder="請輸入姓名"></el-input> </el-form-item> <el-form-item label="性別:" label-width="0.64rem" prop="sex"> <el-select v-model="addKeyPersonForm.sex" placeholder="請選擇"> <el-option label="男" value="1"></el-option> <el-option label="女" value="2"></el-option> </el-select> </el-form-item> <el-form-item label="年齡:" label-width="0.64rem" prop="age"> <el-input v-model="addKeyPersonForm.age" placeholder="請輸入"></el-input> </el-form-item> <el-form-item prop="file" class="upload-img-form" ref="uploadElement"> <el-upload class="upload-img" : ref="uploadxls" action="aaa" ::limit="1" :show-file-list="false" :on-change="handlePictureCardPreview" :before-upload="beforeupload" accept="image/png,image/gif,image/jpg,image/jpeg"> <i v-show="!dialogImageUrl" class="el-icon-upload avatar-uploader-icon"></i> <div v-show="!dialogImageUrl" slot="tip" class="el-upload__text upload__tip">上傳照片</div> </el-upload> </el-form-item> <!--<img :src="dialogImageUrl"/>--> <el-form-item label="身份證號:" prop="idCard"> <el-input v-model="addKeyPersonForm.idCard" placeholder="請輸入身份證號"></el-input> </el-form-item> <el-form-item label="國籍:" label-width="0.64rem" prop="nationlity"> <el-select v-model="addKeyPersonForm.nationlity" placeholder="請選擇"> <el-option label="中國" value="中國"></el-option> </el-select> </el-form-item> <el-form-item label="車牌號:" prop="plateNumber"> <el-input v-model="addKeyPersonForm.plateNumber" placeholder="請輸入車牌號"></el-input> </el-form-item> <el-form-item label="類別:" label-width="0.64rem" prop="userType"> <!--<el-select v-model="addKeyPersonForm.userType" placeholder="請選擇"> <el-option label="精神病人" value="0"></el-option> <el-option label="涉毒" value="1"></el-option> </el-select>--> <el-select v-model="addKeyPersonForm.userType" placeholder="請選擇"> <el-option v-for="item in keyPersonType" :key="item.id" :label="item.dataValue" :value="item.dataKey"> {{item.dataValue}} </el-option> </el-select> </el-form-item> <el-form-item label="戶籍地:" prop="registered"> <!-- <el-select v-model="addKeyPersonForm.huji" placeholder="請選擇"> <el-option label="青島市" value="0"></el-option> <el-option label="北京市" value="1"></el-option> </el-select>--> <el-cascader :options="options" placeholder="請選擇" v-model="addKeyPersonForm.registered" :rules="{type: 'array'}" @change="handleChange" :separator="' '"> </el-cascader> </el-form-item> <el-form-item prop="registeredDetails"> <el-input v-model="addKeyPersonForm.registeredDetails" placeholder="請輸入詳細地址"></el-input> </el-form-item> <el-form-item label="居住地:" prop="domicile"> <!--<el-select v-model="addKeyPersonForm.juzhu" placeholder="請選擇"> <el-option label="青島市" value="0"></el-option> <el-option label="北京市" value="1"></el-option> </el-select>--> <el-cascader :options="options" placeholder="請選擇" :rules="{type: 'array'}" v-model="addKeyPersonForm.domicile" @change="handleChange" :separator="' '"> </el-cascader> </el-form-item> <el-form-item prop="domicileDetails"> <el-input v-model="addKeyPersonForm.domicileDetails" placeholder="請輸入詳細地址"></el-input> </el-form-item> <el-form-item label="經緯度:"> <el-input v-model="position" placeholder="請選擇經緯度" @click.native="showPosition=true"></el-input> </el-form-item> <!--<el-form-item label="所屬人員庫:"> <el-select v-model="addKeyPersonForm.library" placeholder="請選擇"> <el-option label="全國重點人員庫1" value="0"></el-option> <el-option label="全國重點人員庫2" value="1"></el-option> </el-select> </el-form-item>--> <el-form-item label="問題及現實表現:" prop="problem"> <el-input v-model="addKeyPersonForm.problem" placeholder="請輸入問題及現實表現"></el-input> </el-form-item> <el-form-item label="采取措施:" prop="measure"> <el-input v-model="addKeyPersonForm.measure" placeholder="請輸入措施"></el-input> </el-form-item> <el-form-item label="控制人員:" prop="controller"> <el-table :data="addKeyPersonForm.controller" stripe height="1rem" > <el-table-column prop="name" label="姓名" show-overflow-tooltip> </el-table-column> <el-table-column prop="sex" label="性別" width="60"> </el-table-column> <el-table-column prop="birth" show-overflow-tooltip label="出生日期"> </el-table-column> <el-table-column prop="post" show-overflow-tooltip label="職務"> </el-table-column> <el-table-column prop="phone" show-overflow-tooltip label="聯系電話"> </el-table-column> <el-table-column label="操作" width="60"> <template slot-scope="scope"> <el-button @click.native.prevent="deleteRow(scope.$index)" type="text" size="small"> 移除 </el-button> </template> </el-table-column> </el-table> <el-button type="text" icon="el-icon-plus" @click="innerVisible = true">繼續添加</el-button> </el-form-item> <el-form-item label="備注:" prop="remark"> <el-input type="textarea" rows="1" v-model="addKeyPersonForm.remark" placeholder="請輸入備注"></el-input> </el-form-item> <el-form-item label="最后更新時間:" v-if="addKeyPersonForm.updateTime"> <p >{{addKeyPersonForm.updateTime}}</p> </el-form-item> <el-form-item > <el-button type="primary" @click="onSubmit" :disabled="doSubmitFlag">保存</el-button> </el-form-item> </el-form> <!--添加控制人員彈框------------------開始--> <el-dialog width="4.2rem" title="添加控制人員" v-if="innerVisible" :visible.sync="innerVisible" append-to-body :before-close="closeFun"> <personnel-control-add @add-person="addPerson" ref="addForm"></personnel-control-add> </el-dialog> <!--添加控制人員彈框------------------結束--> <!--選擇經緯度彈框------------------開始--> <el-dialog width="5.1rem" title="選擇經緯度" v-if="showPosition" :visible.sync="showPosition" append-to-body :before-close="closePosition"> <personnel-add-position ref="addPosition" @add-position="addPosition" :position-form1="positionForm"></personnel-add-position> </el-dialog> <!--選擇經緯度彈框------------------結束--> </div> </template>
<script> import options from '../../../static/js/country-data.js' import PersonnelControlAdd from './PersonnelControlAdd.vue' import axiosMap from './../../api/map' import axiosControl from './../../api/control' import PersonnelAddPosition from './PersonnelAddPosition.vue' export default { components: { PersonnelAddPosition, PersonnelControlAdd}, name: 'add-keyperson-dialog', props: { dialogType: { type: String }, keypersonList: { type: Object } }, computed: { position: { // 經緯度 // getter get: function () { let str = '' if (this.addKeyPersonForm.longitude !== '' && this.addKeyPersonForm.latitude !== '' && this.addKeyPersonForm.longitude !== null && this.addKeyPersonForm.latitude !== null) { str = this.addKeyPersonForm.longitude + ',' + this.addKeyPersonForm.latitude } return str }, // setter set: function (newValue) { } } }, /* watch: { keypersonList: { // 深度監聽,可監聽到對象、數組的變化 handler (newQuestion, oldQuestion) { this.addKeyPersonForm = Object.assign({}, this.keypersonList) this.dialogImageUrl = Object.assign({}, this.keypersonList).iconUrl }, deep: true } }, */ data () { var checkNumber = (rule, value, callback) => { let regEn = /^[1-9]\d*$/ if (!regEn.test(value)) { callback(new Error('正整數')) } else { callback() } } var checkIdCard = (rule, value, callback) => { let regEn = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/ if (!regEn.test(value)) { callback(new Error('請輸入正確身份證')) } else { // 校驗位按照ISO 7064:1983.MOD 11-2的規定生成,X可以認為是數字10 // 下面分別分析出生日期和校驗位 let num = value.toUpperCase() let len, re len = num.length if (len === 15) { re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/) let arrSplit = num.match(re) // 檢查生日日期是否正確 let dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]) let bGoodDay bGoodDay = (dtmBirth.getYear() === Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) === Number(arrSplit[3])) && (dtmBirth.getDate() === Number(arrSplit[4])) if (!bGoodDay) { callback(new Error('請輸入正確身份證')) } else { // 將15位身份證轉成18位 //校驗位按照ISO 7064:1983.MOD 11-2的規定生成,X可以認為是數字10 let arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] let arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'] var nTemp = 0, i num = num.substr(0, 6) + '19' + num.substr(6, num.length - 6) for (i = 0; i < 17; i++) { nTemp += num.substr(i, 1) * arrInt[i] } num += arrCh[nTemp % 11] callback() } } if (len === 18) { re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/) let arrSplit = num.match(re) // 檢查生日日期是否正確 let dtmBirth = new Date(arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]) let bGoodDay bGoodDay = (dtmBirth.getFullYear() === Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) === Number(arrSplit[3])) && (dtmBirth.getDate() === Number(arrSplit[4])) if (!bGoodDay) { callback(new Error('請輸入正確身份證')) } else { // 檢驗18位身份證的校驗碼是否正確。 //校驗位按照ISO 7064:1983.MOD 11-2的規定生成,X可以認為是數字10 let valnum let arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] let arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'] var nTemp = 0, i for (i = 0; i < 17; i++) { nTemp += num.substr(i, 1) * arrInt[i] } valnum = arrCh[nTemp % 11] if (!isNaN(num.substr(17, 1))) { callback() } if (valnum !== num.substr(17, 1)) { callback(new Error('請輸入正確身份證')) } } } } } var checkPlateNum = (rule, value, callback) => { if (value && value !== '') { let regEn = /(^[京津滬渝冀豫云遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陜吉閩貴粵青藏川寧瓊使領A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9掛學警港澳]{1}$)/ if (!regEn.test(value)) { callback(new Error('請輸入正確車牌號')) } else { callback() } } else { callback() } } return { doSubmitFlag: false, showPosition: false, doUpload: false, keyPersonType: [], // 重點人員類型列表 addKeyPersonForm: Object.assign({}, this.keypersonList), positionForm: { longtitude: this.keypersonList.longitude, latitude: this.keypersonList.latitude }, options: options, // 存放城市數據, innerVisible: false, // 繼續添加彈框 dialogImageUrl: Object.assign({}, this.keypersonList).iconUrl, // 圖片 formData: new FormData(), rules: { // 表單驗證 name: [ { required: true, message: '必填項', trigger: 'blur' } ], age: [ { required: true, message: '必填項', trigger: 'blur' }, { validator: checkNumber, trigger: 'blur' } ], sex: [ { required: true, message: '必填項', trigger: ['blur', 'change'] } ], nationlity: [ { required: true, message: '必填項', trigger: ['blur', 'change'] } ], userType: [ { required: true, message: '必填項', trigger: ['blur', 'change'] } ], idCard: [ { required: true, message: '必填項', trigger: 'blur' }, { validator: checkIdCard, trigger: 'blur' } ], registered: [ { required: true, type: 'array', message: '必填項', trigger: ['blur', 'change'] } ], registeredDetails: [ { required: true, message: '必填項', trigger: 'blur' } ], domicile: [ { required: true, type: 'array', message: '必填項', trigger: ['blur', 'change'] } ], domicileDetails: [ { required: true, message: '必填項', trigger: 'blur' } ], file: [ { required: true, message: '請上傳圖片' } ], plateNumber: [ { validator: checkPlateNum, trigger: 'change' } ] } } }, created () { this.getKeyPersonType() }, methods: { handleChange (value) { }, // 獲取重點人員類型 getKeyPersonType: function () { let that = this let param = { typeCodes: 'userType' } axiosMap.getKeyPersonType(param) .then(res => { if (res.data.code === 200) { that.keyPersonType = res.data.rows['0'].userType that.keyPersonType.forEach(function (item) { if (that.addKeyPersonForm.userType === item.dataValue) { that.addKeyPersonForm.userType = item.dataKey } }) // that.keyPersonType.unshift({dataValue: '全部', dataKey: ''}) } else { that.$message.error({ message: res.data.message }) } }) }, // 添加控制人員 addPerson (person) { this.addKeyPersonForm.controller.push(person) }, // 添加經緯度 addPosition (position) { this.addKeyPersonForm.longitude = position[0] this.addKeyPersonForm.latitude = position[1] this.showPosition = false }, // 刪除某個控制人員 deleteRow (index) { this.addKeyPersonForm.controller.splice(this.addKeyPersonForm.controller[index], 1) }, // 關閉新增控制人員 closeFun () { this.$refs.addForm.$refs.controlForm.resetFields() this.innerVisible = false }, // 關閉經緯度 closePosition () { // this.$refs.addPosition.$refs.addPosition.resetFields() this.showPosition = false }, // 圖片預覽 handlePictureCardPreview (file) { this.dialogImageUrl = file.url this.addKeyPersonForm.file = file.url this.doUpload = true this.$refs['addKeyPersonForm'].validateField('file') }, // 阻止upload的自己上傳,進行再操作 beforeupload (file) { this.formData.append('file', file) return false }, // 上傳重點人員信息 onSubmit: function () { let that = this that.formData = new FormData() that.rules.file = [{ required: true, message: '請上傳圖片' }] if (that.dialogType !== 'add' && !this.doUpload) { that.rules.file = [] that.$refs['uploadElement'].clearValidate() } that.$refs['addKeyPersonForm'].validate((valid) => { if (valid) { that.formData.append('name', that.addKeyPersonForm.name) if (that.addKeyPersonForm.sex === '男') { that.addKeyPersonForm.sex = 1 } else if (that.addKeyPersonForm.sex === '女') { that.addKeyPersonForm.sex = 2 } that.formData.append('sex', that.addKeyPersonForm.sex) that.formData.append('age', that.addKeyPersonForm.age) that.formData.append('idCard', that.addKeyPersonForm.idCard) that.formData.append('nationlity', that.addKeyPersonForm.nationlity) that.formData.append('plateNumber', that.addKeyPersonForm.plateNumber) that.formData.append('userType', that.addKeyPersonForm.userType) that.formData.append('longitude', that.addKeyPersonForm.longitude) that.formData.append('latitude', that.addKeyPersonForm.latitude) that.formData.append('registered', that.addKeyPersonForm.registered.join('-')) that.formData.append('registeredDetails', that.addKeyPersonForm.registeredDetails) that.formData.append('domicile', that.addKeyPersonForm.domicile.join('-')) that.formData.append('domicileDetails', that.addKeyPersonForm.domicileDetails) that.formData.append('problem', that.addKeyPersonForm.problem) that.formData.append('measure', that.addKeyPersonForm.measure) that.formData.append('controller', JSON.stringify(that.addKeyPersonForm.controller)) that.formData.append('remark', that.addKeyPersonForm.remark) if (that.dialogType === 'add') { that.$refs.uploadxls.submit() // 提交時觸發了before-upload函數 that.doSubmitFlag = true axiosControl.saveNewKeyPerson(that.formData) .then(res => { that.doSubmitFlag = false if (res.data.code === 200) { that.$message({ type: 'success', message: '添加成功' }) that.$refs.addKeyPersonForm.dialogImageUrl = 'none' that.$refs.uploadxls.clearFiles() that.$refs.addKeyPersonForm.resetFields() that.fileName = '' that.uploadForm = new FormData() that.$emit('savePersonSuccess') } else { that.$message.error({ message: res.data.message }) } }) /* .catch(err => { that.$message.error({ message: err }) }) */ } else { if (!that.doUpload) { that.formData.append('iconUrl', that.addKeyPersonForm.iconUrl) } // 還要傳id that.formData.append('id', that.addKeyPersonForm.id) that.doSubmitFlag = true axiosControl.saveEditKeyPerson(that.formData) .then(res => { that.doSubmitFlag = false if (res.data.code === 200) { that.$message({ type: 'success', message: '添加成功' }) that.$refs.addKeyPersonForm.dialogImageUrl = 'none' that.$refs.uploadxls.clearFiles() that.$refs.addKeyPersonForm.resetFields() that.fileName = '' that.uploadForm = new FormData() that.$emit('savePersonSuccess') } else { that.$message.error({ message: res.data.message }) } }) } } else { this.$message({ type: 'warning', message: '請填寫正確格式' }) return false } }) } } } </script>
<style scoped> .add-keyperson-dialog{ position:relative; height:7.2rem; overflow:auto; } .add-keyperson-dialog .demo-form-inline{ font-size:0.13rem; color:#666; } /*上傳圖片樣式*/ .add-keyperson-dialog .upload-img-form{ width: 1rem; height: 1.35rem; position: absolute; right:0.2rem; top:0rem; border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; text-align: center; } .add-keyperson-dialog .upload-img{ width: 1rem; height: 1.35rem; overflow:hidden; } .add-keyperson-dialog .upload-img:hover { border-color: #409EFF; color: #409EFF; } .add-keyperson-dialog .avatar-uploader-icon { position:relative; z-index:100; font-size: 0.3rem; color: #8c939d; width: 0.9rem; height: 1.35rem; line-height: 1rem; text-align: center; } .add-keyperson-dialog .upload-img:hover .avatar-uploader-icon { color: #409EFF } .add-keyperson-dialog .avatar { width: 100%; height: auto; display: block; } .add-keyperson-dialog .upload__tip { font-size: 0.13rem; text-align: center; position: relative; z-index:10; top: -0.7rem; } </style>
關于如何在vue中使用elementUI上傳表單和圖片就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。