Vue Element-ui 图片跟随表单一起上传

实现例如用户注册信息填写,商品发布等等需求时,通常会有需要上传图片的需求。这个时候我们可以使用Element-UI的el-upload组件进行图片上传。

<el-upload
  action="https://jsonplaceholder.typicode.com/posts/"
  list-type="picture-card"
  :on-preview="handlePictureCardPreview"
  :on-remove="handleRemove">
  <i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
  <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<script>
  export default {
    data() {
      return {
        dialogImageUrl: '',
        dialogVisible: false
      };
    },
    methods: {
      handleRemove(file, fileList) {
        console.log(file, fileList);
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      }
    }
  }
</script>

但是我们如果直接将这段代码放上去使用,不修改的话就会出现几个问题。图片一旦选择就直接通过后端上传到了数据库,如果用户想要修改上传的图片,那旧图片却已经在数据库中存在。无法实现图片与表单中的其他数据一起上传的需求。

所以为了实现图片跟随表单上传的需求,我们需要先关闭el-upload的自动上传,再将图片信息上传到一个FormData 对象中,当提交表单的时候,先将这个对象上传到后端,后端将图像存储到数据库中,并返回相应的图片信息,前端获取到这些图片信息后,赋值到相应的表单数据,再上传整张表单。

前端:

<el-form-item label="图片"  prop="img">
    <el-input v-model="ruleForm.img" v-if="false"></el-input>
    <el-upload
               action=""
               ref="uploadimg"
               list-type="picture-card"
               :auto-upload="false"
               :data="ruleForm"
               :file-list="ruleForm.img"
               :on-preview="handlePictureCardPreview"
               :on-remove="handleRemove"
               :on-change="handleChange"
               :http-request="uploadFile">
        <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="adoptFormdialogVisible">
        <img width="100%" :src="adoptFormdialogImageUrl" alt="">
    </el-dialog>
</el-form-item>

<script>
    export default {
    name: "Tab",
    data() {
      return {
        dialogFormVisible: false,
        adoptFormdialogVisible: false,
        adoptFormdialogImageUrl:'',
        classify: [],
        hasLogin: false,
        dialogFormVisible: false,
        ruleForm: {
          id: '',
          name: '',
          introduce: '',
          price: '',
          banner: '',
          classify_id: '',
          status: '1',
          user_id: '1'
        },
        rules: {
          name: [
            { required: true, message: '请输入标题', trigger: 'blur' },
            { min: 3, max: 25, message: '长度在 3 到 25 个字符', trigger: 'blur' }
          ],
          introduce: [
            { required: true, message: '请输入摘要', trigger: 'blur' }
          ],
          price: [
            { required: true, message: '请输入价格,自动保留两位小数', trigger: 'blur' }
          ],
          classify: [
            { required: true, message: '请选择商品类别', trigger: 'blur' }
          ]
        },
        activeTab: 'first',
        showHeader: false,
        formData:'' 
      };
    },
    methods: {
      submitForm(formName){// 用户点击上传表单后
        this.$refs[formName].validate((valid) => {
          if (valid) {
            this.formData = new FormData()
            this.$refs.uploadimg.submit();
            // 先上传图片,图片存在formData中
            this.$axios.post("/file/upLoad", this.formData).then( res =>{
              console.log(res)
              this.ruleForm.banner = res.data.data // 返回图片相关信息,例如图片名称
              // 表单上传
              this.$axios.post("/goods/saveGoods", this.ruleForm).then( res=> {
                if(res.data.code == 200){
                  this.$message({
                    message: res.data.msg,
                    type: 'success'
                  });
                  //传值给父组件关闭弹框
                  this.$emit("func", false)
                  this.$refs[formName].resetFields();

                }else{
                  this.$message.error(res.data.msg);
                }
                this.dialogFormVisible = false
              })
            }).catch( res=>{
              console.log(res)
            })
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      }
</script>

图片上传工具类:

public class UploadUtils {
    // 项目根路径下的目录  -- SpringBoot static 目录相当于是根路径下(SpringBoot 默认) 
    public final static String IMG_PATH_PREFIX = "static/imgs";
 
    public static File getImgDirFile(){
 
        // 构建上传文件的存放 "文件夹" 路径
        String fileDirPath = new String("src/main/resources/" + IMG_PATH_PREFIX);
 
        File fileDir = new File(fileDirPath);
        if(!fileDir.exists()){
            // 递归生成文件夹
            fileDir.mkdirs();
        }
        return fileDir;
    }
}

图片上传接口:修改图片名称,避免图片名称冲突导致不可上传图片,并返回图片名称

@RestController
@RequestMapping("/file")
public class FileController {
    @PostMapping(value = "/upLoad")
    @ResponseBody
    public Result upLoad(@RequestParam(value = "file", required = false) MultipartFile[] multipartFiles){

        StringBuffer sb = new StringBuffer();
        File fileDir = UploadUtils.getImgDirFile();

        try {
            // 不传图片,此处捕获空指针异常,代码照常运行
            for(int x = 0; x<multipartFiles.length; x++){
                MultipartFile uploadFile = multipartFiles[x];
                // 存储图片
                File uploadDir = new File(fileDir.getAbsolutePath() + File.separator);
                if ( uploadFile != null) {
                    //获得上传文件的文件名
                    String oldName = uploadFile.getOriginalFilename();
                    System.out.println("[上传的文件名]:" + oldName);
                    String uuid = UUID.randomUUID().toString().replace("-", "");
                    String newName = uuid + oldName;
                    System.out.println("[新文件名]:" + newName);
                    if (sb.toString().equals("")){
                        sb.append(newName);
                    }else {
                        sb.append("|" + newName);
                    }
                    System.out.println(sb.toString());
                    //我的文件保存在static目录下的avatar/user
                    File pic = new File(uploadDir, newName);
                    try {
                        //保存图片
                        uploadFile.transferTo(pic);
                        //返回成功结果,附带文件的相对路径
                    }catch (IOException e) {
                        System.out.println("=====捕获异常=====");
                        e.printStackTrace();
                    }
                }
            }
        }catch (NullPointerException e){
            System.out.println("=====捕获异常=====");
            e.printStackTrace();
        }
        // 存储其它数据
        return Result.succ(sb.toString());
    }
}

表单上传接口:java

@PostMapping("saveGoods")
public Result saveGoods(@RequestBody Goods goods) {
    goodsService.saveGoods(goods);
    return Result.succ("成功");
}
  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Vue 是一个流行的 JavaScript 框架,用于构建用户界面和单页面应用程序。Element UI 是一个基于 Vue.js 的组件库,提供了丰富的 UI 组件和工具。在 Vue 中使用 Element UI 构建表单,可以通过循环来动态生成表单项并进行验证。 首先,我们可以使用 Vue 的 v-for 指令来循环渲染表单项。通过遍历数据源(如数组或对象)来动态生成表单字段,例如输入框、下拉框、复选框等。这样就可以实现根据数据源的变化而动态生成不同数量的表单项,方便灵活地管理表单内容。 其次,通过 Element UI 提供的验证规则和验证器,可以实现对表单的循环验证。我们可以为每个表单项设置相应的验证规则(如必填、格式验证等),并通过验证器对整个表单进行验证。在循环中,可以动态添加、修改或删除验证规则,以实现对动态生成的表单项的实时验证。 另外,可以利用 Element UI 提供的表单组件和事件处理机制来实现更进一步的表单循环验证。例如,可以监听表单项的输入变化、聚焦和失焦事件,在相应的事件处理函数中进行数据的验证和反馈。这样就可以及时提示用户输入的正确与否,提升用户体验。 总之,使用 VueElement UI 可以很容易地实现表单的循环验证。通过动态生成表单项、设置验证规则和事件处理,可以灵活地管理和验证表单数据,提供更好的用户交互体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值