elementui的el-form和el-upload上传文件和表单数据

表单数据和文件上传四种思路:

1、文件和表单数据一起上传到后端,即后端一个接口接收文件和表单数据(这种是比较古老的方法,后端接口复杂度也大,且不易实现上传文件进度条等功能,不推荐)

2、先上传文件,然后后端保存文件(先不进行数据库写入),返回一个文件的url给前端,前端收到url后和其他表单数据一起提交给后端,后端再一起写入数据库(要求后端将上传文件的接口独立出来,推荐)

3、先上传文件,然后后端保存文件,并写入数据库,得到数据库id,将数据库id返回给前端,前端将表单数据和数据库id一起发送给后端,然后后端根据数据库id找到该记录,在更新表单数据到该记录

4、先上传表单数据,然后后端保存表单数据,写入数据库,然后前端在点击上传文件(并传递之前上传表单数据的数据库id),后端接收到文件保存后,将url更新进表单数据里(这种方法最容易实现,但是用户需要两次操作才能更新表单数据和文件,不像第二和第三种,只需要点击提交表单后就可以更新)

使用el-upload上传文件

使用el-upload还需要注意的是:

​ action属性发送的请求是使用内部封装的ajax请求,所以不会经过你自己封装的axios,所以如果你配置来代理,需要你自己为该请求添加代理前缀,如果使用了token身份校验,你还需要为本次请求添加请求头

​ el-upload的name属性的就是本次发送请求文件的参数名,需要将他更改为后端需要的参数名

接下来是使用上面说的第二种方法来进行表单数据和文件一起上传

html部分

      <el-form :rules="categoryRules" ref="categoryRuleForm" :model="categoryForm">
        <el-form-item label="分类名称" label-width="120px" prop="category_name">
          <el-input v-model="categoryForm.category_name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="分类图片" label-width="120px" prop="category_pic">
          <el-upload
          list-type="picture-card"
          :limit="1"
          :on-exceed="handleExceed"
          name="category_pic"
          action="/api/category/uploadPic"
          :headers="headerObj"
          :on-remove="handleRemove"
          :on-success="handleCategoryPicSuccess"
          :file-list="fileList"
          :before-upload="beforeCategoryPicUpload"
          >
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url" alt=""
              >
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePictureCardPreview(file)"
                >
                  <i class="el-icon-zoom-in"></i>
                </span>
                <span
                  v-if="!disabled"
                  class="el-upload-list__item-delete"
                  @click="handleDownload(file)"
                >
                  <i class="el-icon-download"></i>
                </span>
                <span
                  v-if="!disabled"
                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </div>
          </el-upload>
          <el-dialog :visible.sync="dialogVisible">
            <img width="100%" :src="dialogImageUrl" alt="">
          </el-dialog>
        </el-form-item>
      </el-form>

js部分

<script>
import {
    
    getToken} from '@/utils/auth'
import {
    
     getCategoryList, addCategory, updateCategory, deleteCategory, deleteCategoryPic } from '../../api/category'
export default {
    
    
  name: '',
  data () {
    
    
    return {
    
    

      categoryForm: {
    
    
        category_name: '',  // 分类名称
        category_pic: '', // 分类图片
      },

      // el-upload的请求头
      headerObj: {
    
    
        Authorization: `Bearer ${
      
      getToken()}`,  
      },

      fileList: [], // 上传时的图片列表(这里的图片将会显示出缩略图)

      // 大图预览相关
      dialogImageUrl: '',
      dialogVisible: false,
      disabled: false
    }
  },
  mounted () {
    
    
  },
  methods: {
    
    
    // 添加分类
    addCategory() {
    
    
          this.addDialogFormVisible = false
          let result = await addCategory({
    
    
            category_name: this.categoryForm.category_name,
            category_pic: this.categoryForm.category_pic,
          })
          if(result.code === 200){
    
    
            this.$message.success(result.message)
            this.getCategoryList()
          }else{
    
    
            this.$message.error(result.message)
          }
    },
    // 上传图片成功
    handleCategoryPicSuccess(res, file) {
    
    
      // 将服务器返回的文件url地址赋值给表单的category_pic,这样就可以在表单提交时将图片地址提交到服务器
      this.categoryForm.category_pic = res.data.category_pic
      this.getCategoryList()
      // 提示信息
      this.$message({
    
    
        message: '图片上传成功',
        type: 'success'
      });
    },
    // 上传图片前
    beforeCategoryPicUpload(file) {
    
    
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
      const isLt1M = file.size / 1024 / 1024 < 1;

      if (!isJPG) {
    
    
        this.$message.error('上传头像图片只能是 JPG / PNG 格式!');
      }
      if (!isLt1M) {
    
    
        this.$message.error('上传头像图片大小不能超过 1MB!');
      }
      return isJPG && isLt1M;
    },
    // 图片超出限制
    handleExceed(files, fileList) {
    
    
      this.$message.error('当前限制选择 1 张图片!');
    },
    // 点击删除按钮
    async handleRemove(file) {
    
      // 删除图片
      // 删除缩略图图片
      this.fileList.splice(this.fileList.indexOf(file), 1);

      // 发送请求删除服务器图片
      let result = await deleteCategoryPic({
    
    
        category_pic: this.categoryForm.category_pic,
      })
      if(result.code === 200){
    
    
        this.$message.success(result.message)
      }else{
    
    
        this.$message.error(result.message)
      }
    },
    // 点击大图预览按钮
    handlePictureCardPreview(file) {
    
    
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 点击下载按钮
    handleDownload(file) {
    
    
      // 提示
      this.$message({
    
    
        message: '暂未开发',
        type: 'danger'
      });
    }
  }
}
</script>

猜你喜欢

转载自blog.csdn.net/cocogogogo/article/details/124347225