首页 前端知识 vue el-upload 实现图片上传和回显

vue el-upload 实现图片上传和回显

2024-05-12 00:05:04 前端知识 前端哥 1015 576 我要收藏

使用vue+el-upload 实现图片上传,可浏览大图,可删除功能。

第一步

首先要搞定图片上传的接口和服务器,写在index.js里,通过export default{}抛出。

import Fetch from "./fetch";
import axios from "axios";
export default {
  // 新上传图片
  async uploadImage(file) {
    return new Promise((resolve, reject) => {
      let headers = {
        "Content-Type": "multipart/form-data"   //设置响应头
      };
      let data = new FormData();
      data.append("filedata", file);
      axios({
        url: "/fdfs/imageupload",  //要上传的地址
        data: data,
        method: "POST",
        header: headers
      })
        .then(suc => {
          if (suc.data) {
            resolve(suc.data);
          } else {
            resolve(false);
          }
        })
        .catch(err => {
          reject(false);
        });
    });
  },
};

第二步

从elementUI里准备选择一个喜欢的上传组件

<div>
    <el-upload
               action="#"  //必选参数,上传的地址
               ref="upload"
               list-type="picture-card"  //文件列表的类型(	text/picture/picture-card)
               :http-request="UploadImage"   //覆盖默认的上传行为,可以自定义上传的实现(function)
               :on-preview="handlePictureCardPreview" //点击文件列表中已上传的文件时的钩子
               :on-remove="handleRemove"  //文件列表移除文件时的钩子
               :before-upload="beforeAvatarUpload"  //上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
               :limit="2"  //最大允许上传个数
               :on-change="handleChange" //文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
               :on-exceed="handleExceed"  //文件超出个数限制时的钩子
               :file-list="formData.fileList"  //上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]
               accept=".jpg,.jpeg,.png"  //文件格式限制
               >
        <i class="el-icon-plus"></i>
    </el-upload>
    <!--下面是点击放大图片的弹窗-->
    <el-dialog :visible.sync="dialogVisible" append-to-body>
        <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
</div>

第三步 

开始写方法来实现功能,因为我写的是个添加编辑子组件,所以从父组件里拿了数据。

<script>
import interfaces from "@/interfaces/index";  //注意引入接口文件
export default {
    components: {},
  props: {
    // 从父组件接收数据参数
    editRuleForm:{
        type: Object,
        default (){
        return null;
      },
    },
  },
  data() {
    return {
        dialogImageUrl: '', //这个是放大展示弹框里的图片
        dialogVisible: false,
        //用于给后端传参的字段
        ruleForm:{ 
            picturePath:[],  //图片数组
        },
        //新图片数组
        formData: {
            fileList: [],//图片数组
        },
    };
  },
  methods: {
    //获取父组件的数据参数editRuleForm
    geteditRuleForm(){
      this.ruleForm = this.editRuleForm
      //判断接口里传回来的图片数组里有没有图片,有的话就赋值给formData.fileList[],这样图片回显功能就ok了。
      if(this.ruleForm.picturePath.length > 0){
        this.formData.fileList = this.ruleForm.picturePath.map(item => {
          return{
            url:item
          }
        })
      } 
    },
    //提交
    submitForm() {
      this.$refs['ruleForm'].validate(async (valid) => {
        if (valid) {
          //查找formData.fileList[]里的图片地址
          let fileListArr = [];
          this.formData.fileList.forEach(function(item,index,) {
            fileListArr.push(item.url);
          });
          this.ruleForm.picturePath = fileListArr
          //传回给父组件
          this.$emit('benefitaddSubmit', this.ruleForm);
        }
      });
    },
    //取消
    cancel() {
      if (this.$refs["ruleForm"]) {
        this.$refs["ruleForm"].resetFields();
        this.$refs["ruleForm"].clearValidate();
      }
      this.$emit('benefitaddCancel', this.ruleForm);
    },
    
    //删除图片
    handleRemove(file, fileList) {
      //   判断是否是正确格式图片才能执行删除
      if (file && file.status === "success") {
        let Pics = this.formData.fileList;
        //查找对比点击图片的url地址和formData.fileList[]里的url地址是否有对应的,一样的话就删除
        Pics.forEach((item, index) => {
          if (file.url == item.url) {
            Pics.splice(index, 1);
          }
        });
      }
    },
     //查看大图
      handlePictureCardPreview(file) {
        this.dialogImageUrl  = file.url;
        this.dialogVisible = true;
      },
      //图片发生改变的时候触发
      handleChange(file, fileList) {
        console.log("handleChange-fileList",fileList);
        console.log("handleChange-file",file);
    },
    //最重要的地方!!!上传!!!
    async UploadImage(file) {
     //搞清楚后端需要的参数
     let res = await interfaces.uploadImage(file.file);
      //将上传图片的uid和接口返回的地址存起来
      let obj = {
        uid: file.file.uid,
        url: res,
      };
      this.formData.fileList.push(obj);

      console.log("上传formData.fileList:",this.formData.fileList);
    },

    // 上传检测
    beforeAvatarUpload(file) {
      //限制图片上传的格式
      const types = ["image/jpg", "image/png","image/jpeg"];
      const isImage = types.includes(file.type);
      //限制图片上传的大小
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isImage) {
        this.$message.error("上传图片只能是 JPG、JPEG、PNG 格式!");
        // this.$refs.upload.handleRemove(file);
      }
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过 2MB!");
        // this.$refs.upload.handleRemove(file);
      }
      return isImage && isLt2M;
    },
    //控制上传数量提示
    handleExceed(files, fileList) {
      this.$message.warning(`最多上传2个文件`);
    },
  },
  created() {
    this.geteditRuleForm()
    console.log("editRuleForm:",this.editRuleForm)
  },
};
</script>

然后就OK啦,下面是效果。

图片排列的样式使用了 display: flex;  

转载请注明出处或者链接地址:https://www.qianduange.cn//article/8259.html
标签
评论
发布的文章

JSON三种数据解析方法

2024-05-22 09:05:13

使用nvm管理(切换)node版本

2024-05-22 09:05:48

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!