Vue-ElementUI 表单(Form)+图片上传(upload)+表单验证

时间:2025-03-20 09:22:05
<template> <div class="reg-container"> <el-form :model="regForm" :rules="regRules" ref="myRegForm" label-width="auto" class="reg-form" status-icon> <h2 class="reg-title">用户注册</h2> <el-form-item label="用户姓名" prop="username"> <el-input ="" placeholder="请输入用户姓名" size="mini"></el-input> </el-form-item> <el-form-item label="用户密码" prop="password"> <el-input ="" placeholder="请输入用户密码" size="mini" show-password></el-input> </el-form-item> <el-form-item label="真实姓名" prop="realname"> <el-input ="" placeholder="请输入真实姓名" size="mini"></el-input> </el-form-item> <el-form-item label="邮箱地址" prop="email"> <el-input ="" placeholder="请输入邮箱地址" size="mini"></el-input> </el-form-item> <el-form-item label="电话号码" prop="phone"> <el-input ="" placeholder="请输入电话号码" size="mini"></el-input> </el-form-item> <el-form-item label="性别"> <!-- 此处使用了ElementUI的单选框组 v-model双向绑定性别,这里绑定的 就是用户最终选择得单选框--> <el-radio-group v-model=""> <!-- :label:这里相当于之前单选框中value属性 --> <el-radio :label="1"></el-radio> <el-radio :label="0"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="权限"> <el-radio-group v-model=""> <el-radio :label="1">管理员</el-radio> <el-radio :label="0">用户</el-radio> </el-radio-group> </el-form-item> <!-- 此处要校检用户上传成功后返回的地址 --> <el-form-item label="上传头像" prop="path"> <!-- 此处使用了ElementUI中的 Upload组件 action:异步上传的目的地,注意这里就是完整地址,不需要我们自己 书写dao层中函数了 list-type="picture-card" 上传的UI界面 text/picture/picture-card :limit="数字":表示最多上传几个文件 :on-exceed="handleExceed":表示上传超过了个数执行的函数 :before-upload="beforeAvatarUpload":上传之前最后一个执行的函数 :on-success="handleAvatarSuccess":表示上传成功之后执行的函数 :on-remove="handleRemove" 点击垃圾桶删除上传文件执行的钩子函数 :on-preview="handlePictureCardPreview" 点击放大镜查看上传文件时执行的 钩子 :show-file-list="true" 是否显示已经上传的文件列表 :file-list="fileList" 表示已经上传的文件列表 --> <el-upload action=":9527/sysFile/fileUpload" list-type="text" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :limit="1" :on-success="handleAvatarSuccess" :on-exceed="handleExceed" :file-list="fileList" :show-file-list="true" :before-upload="beforeAvatarUpload" ref="up" class="up"> <i class="el-icon-plus"></i> </el-upload> <!-- 此处使用了ElementUI中的 Dialog对话框 :="dialogVisible":如果绑定true,则 对话框显示,false对话框隐藏 --> <el-dialog :="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt=""> </el-dialog> </el-form-item> <el-form-item> <el-button type="primary" class="btn" @click="submitForm('myRegForm')" round size="small">注册</el-button> <el-button @click="resetForm('myRegForm')" round size="small">取消</el-button> </el-form-item> </el-form> </div> </template> <script> import dao from '@/api/dao' export default { data() { return { /* 控制上传对话框显示与否,默认false不显示 */ dialogVisible:false, /* 对话框内放置的上传图片的地址 */ dialogImageUrl:'', /* 已经上传的文件列表,本例未使用 */ fileList:[], regForm: { username:'', password:'', realname:'', email:'', phone:'', /* 默认是男 0 */ gender:0, /* 默认用户 0 */ role:0, /* 此路径是上传成功后返回的图片保存地址 */ path:'', }, regRules: { username: [ { required: true, message: '请输入用户姓名', trigger: 'blur' }, { min: 6, max: 10, message: '长度为6到10个字符', trigger: 'blur' }, { pattern:/^[a-zA-Z0-9_]*$/, message:'由英文数字下滑线组成',trigger:'blur'} ], password:[ { required: true, message: '请输入用户密码', trigger: 'blur' }, { min: 6, max: 32, message: '长度为6到32个字符', trigger: 'blur' }, { pattern:/^[a-zA-Z0-9_]*$/, message:'由英文数字下滑线组成',trigger:'blur'} ], realname:[ { required: true, message: '请输入真实姓名', trigger: 'blur' }, { min: 6, max: 10, message: '长度为6到10个字符', trigger: 'blur' } ], email:[ { required: true, message: '请输入邮箱地址', trigger: 'blur' }, { pattern:/^[\w]+@[\w]+(\.[\w]+)+$/, message:'请输入合法邮箱地址',trigger:'blur'} ], phone:[ { required: true, message: '请输入电话号码', trigger: 'blur' }, { pattern:/^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8}$/, message:'请输入合法电话号码',trigger:'blur'} ], path:[ { required: true, message: '请上传头像' }, ], } }; }, methods: { //注册 submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { dao.reg(this.regForm).then(response=>{ this.$message({ type:response.data.flag?'success':'error', message:response.data.msg, showClose:true, }) if(response.data.flag){ setTimeout(() => { this.$router.push('/') }, 1200); } }) } else { console.log('error submit!!'); return false; } }); }, /* 重置表单 */ /* formName形参 就是表单的ref值 */ resetForm(formName) { /* this.$ 相当于 () resetFields():对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 */ this.$refs[formName].resetFields(); }, /* 传递参数超过个数 file:就表示用户上传成功的文件 fileList:就表示已经上传的文件列表 */ handleExceed(file,fileList){ this.$message.error('最多上传一张头像...'); }, /* 上传之前的钩子此处多用来进行上传时的格式查询等等 */ beforeAvatarUpload(file){ /* 匹配 MIME 格式 */ const isJPG = file.type === 'image/jpeg'; /* 这里表示不能大于500k */ const isLt2M = file.size / 1024 / 1024 < 0.5; if (!isJPG) { this.$message.error('上传头像图片只能是 JPG 格式!'); } if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 500k!'); } return isJPG && isLt2M; }, /* 文件上传成功时的钩子 response:上传成功返回的响应 file:每次上传的文件对象 fileList:目前所有已经上传的文件数组 */ handleAvatarSuccess(response, file, fileList){ console.log(response,file,fileList) /* 一般在上传成功后在此处进行业务逻辑,例如将返回的路径添加进表单双向绑定的data中的对象 */ /* { "code":null, "flag":true, "msg":"上传成功~", "data":{ "fileId":null, "fileName":"1", "fileSize":48558, "path":":9528/" } } */ if(response.flag){ /* 将返回的路径添加进封装路径的表单项属性 */ //() /* 上传成功后将返回的路径赋值给表单项中封装的路径 */ this.regForm.path = response.data.path } }, /* 文件移除的钩子 file:点击的要删除的已经上传成功的文件对象 fileList:目前所有已经上传的文件数组 */ handleRemove(file, fileList) { /* 此处进行上传文件被删除之后的逻辑 */ //((),1) /* 将已经保存的上传成功的路径恢复为空串 */ this.regForm.path = '' }, /* 点击放大镜查看上传文件详细信息时执行 */ handlePictureCardPreview(file) { /* 填充路径 */ this.dialogImageUrl = this.regForm.path /* 对话框显示 */ this.dialogVisible = true; }, } } </script> <style scoped> /* 设置最外侧div大容器 */ .reg-container{ /* 设置容器绝对定位 */ position: absolute; /* 设置宽度和高度 */ width:100vw; height:100vh; /* 设置div的背景图 后面的 no-repeat 表示如果尺寸不合适,则不重叠摆放 */ background: url("../../assets/") no-repeat; /* 设置背景图宽高 */ background-size: 100vw 100vh; /* 设置背景图永远固定摆放,不随着用户放大缩小浏览器而改变 */ background-attachment: fixed; /* 开启弹性盒子 */ display: flex; /* 默认情况下 项目从左往右排列,从左往右是主轴 main axis 从上往下是交叉轴 cross axis 但是这不是固定的,如果 flex-direction更改为 column,则项目从上往下排列,主轴从上往下 交叉轴从左往右 由于本例只有一个项目,则以下语句多余 */ /* flex-direction: row; */ /* 主轴居中排列 */ justify-content: center; /* 交叉轴居中排列 */ align-items: center; } /* 设置表单样式 */ .reg-form{ /* 表单宽度 */ width:350px; background-color: rgb(255, 255, 255,0.7); /* 矩形边框变为圆角,数字越大越圆,设置为50%变为圆球,不得设置table表格 */ border-radius: 40px; /* 给这个表单开启弹性盒子 */ display: flex; /* 设置内部的项目从上往下排列 ,默认是从左往右 */ flex-direction: column; /* 表单内文本居中 */ text-align: center; /* 交叉轴居中 */ align-items: center; box-shadow: 15px 15px 15px silver; } .btn{ margin-left: -70px; } /* elementUI的 el标签全部自带 class="标签名" */ .el-input{ width:160px; } /* 设置上传控件的宽度 */ .up{ width:160px; } </style>