element Ui 单张图片上传组件封装和调用示例 包含表单验证,提交,重置功能 状态包含图片上传成功、上传中请等待、图片删除、图片重置功能

简介:
element Ui 单张图片上传组件封装和调用示例
包含上传时表单验证,提交,重置功能
状态包含图片上传成功、图片上传中请等待、图片删除、图片重置功能
上传中隐藏+号,删除后显示+号,重置后显示+号,上传失败显示+号
示例图片:
在这里插入图片描述
组件代码:

<!--
 * @Descripttion: 
 * @version: 
 * @Author: sueRimn
 * @Date: 2020-05-26 14:19:55
 * @LastEditors: sueRimn
 * @LastEditTime: 2020-06-19 10:48:22
--> 
<!-- 图片上传封装示例 -->
<template>
  <div>
    <!-- limit:             允许上传文件个数           -->
    <!-- multiple:          是否支持多选文件           -->
    <!-- on-success:        文件上传成功时的钩子        -->
    <!-- before-upload:     上传文件之前的钩子          -->
    <!-- on-preview:        点击已上传完成的文件时      -->
    <!-- on-remove:         文件列表移除文件时的钩子    -->
    <!-- on-error:          文件上传失败的钩子          -->
    <el-upload
      action="https://jsonplaceholder.typicode.com/posts/"
      list-type="picture-card"
      name="156511"
      :limit="1"
      :multiple="false"
      :on-success="handleAvatarSuccess"
      :before-upload="beforeAvatarUpload"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :class="{hidden:hiddens}"
      :on-error="handleAvatarError"
      :disabled="disabled"
      ref="oneUploadImage"
    >
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt />
    </el-dialog>
  </div>
</template>

<script>
/**
 * @param {
 *
 *父组件与子组件之间的交互内容
 *  1.上传文件成功      上传按钮的隐藏
 *  2.删除上传好的文件  父组件需清空url
 *  3.删除上传好的文件  子组件需要展示上传按钮
 *  4.当文件还在上传中并未上传完成需给父组件相应的状态
 *  5.当文件上传失败,需显示上传按钮更换父组件的上传中的状态
 *
 * }
 */
export default {
  name: "updataImage",
  components: {},
  props: {
    /**
     * @param {
     * 权限校验&& + 号的显示隐藏
     * }
     */
    hidden: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      imageUrl: "",
      dialogImageUrl: "",
      dialogVisible: false,
      //防止图片多重点击,校验完成好上传格式即disabled
      disabled: false
    };
  },
  created() {},
  mounted() {},
  methods: {
    /**
     * @param {
     * 上传文件之前的钩子
     * }
     */
    beforeAvatarUpload(file) {
      const typeList = ["jpg", "jpeg"];
      const fileName = file.name;
      //截取图片格式
      const extension = fileName.substr(fileName.lastIndexOf(".") + 1);
      const isRT = typeList.includes(extension);
      const isLt2M = file.size / 1024 / 1024 < 5;

      if (!isRT) {
        this.$message.error("上传头像图片只能是 JPG/jpeg 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 5MB!");
      }
      if (isRT && isLt2M) {
        //校验成功即意味着上传中,隐藏上传按钮传入true
        this.updataState(true);
        //校验完成disabled  禁用上传按钮
        this.disabled = true;
      }
      return isRT && isLt2M;
    },
    /**
     * @param {
     * 照片正在上传中,请等待的状态
     * }
     */
    updataState(v) {
      this.$emit("updataState", v);
    },
    /**
     * @param {
     * 文件上传成功的钩子
     * }
     */
    handleAvatarSuccess(res, file) {
      //文件上传成功意味着,父组件处理了
      // this.updataState(false);
      this.imageUrl = URL.createObjectURL(file.raw);
      //上传成功,解开disabled
      this.disabled = false;
      this.$emit("activeSuccess", this.imageUrl);
    },
    /**
     * @param {
     * 文件上传失败的钩子
     * }
     */
    handleAvatarError() {
      // 父组件处理了
      // this.updataState(false);
      //上传失败解开disabled
      this.disabled = false;
      this.$emit("activeError");
    },

    /**
     * @param {
     * 从已上传列表中移除文件时
     * }
     */
    handleRemove(file, fileList) {
      this.$emit("activeRemove");
    },
    /**
     * @param {
     * 打开弹窗放大查看照片
     * }
     */
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    /**
     * @param {
     * 表单重置调用函数
     * }
     */
    // 1).父组件控制加号要显示
    // 2).父组件上传中状态要改变
    // 3).本组件disable要为false
    // 4).父组件url要为空
    // 5).本组件reset
    resetUpload() {
      //调用父组件文件删除方法直接解决1)2)4)直接在父组件中调用不是更好?
      // this.$emit("activeRemove");
      //解决3)
      this.disabled = false;
      //解决4)
      this.imageUrl = "";
      //解决5)
      this.$refs.oneUploadImage.clearFiles();
    }
  },
  computed: {
    hiddens() {
      return this.hidden;
    }
  }
};
</script>
<style lang='scss'>
.hidden {
  .el-upload--picture-card {
    display: none !important;
  }
}
</style>

调用组件示例:

<!--
 * @Descripttion: 
 * @version: 
 * @Author: sueRimn
 * @Date: 2020-06-18 16:05:18
 * @LastEditors: sueRimn
 * @LastEditTime: 2020-06-19 10:52:47
--> 
<!-- 单张图片上传调用示例
      element Ui 单张图片上传组件封装和调用示例
      包含表单验证,提交,重置功能
      状态包含图片上传成功、图片删除、图片重置功能
      上传中隐藏+号,删除后显示+号,重置后显示+号,上传失败显示+-->
<template>
  <div class="img-box">
    <el-form
      label-width="120px"
      style="margin-left:-120px;"
      :rules="formRules"
      ref="ruleForm"
      :model="form"
    >
      <el-form-item label="上传单张照片" prop="imgUrl">
        <one-image
          ref="oneImage"
          :hidden="hidden"
          @updataState="updataState"
          @activeRemove="activeRemove"
          @activeSuccess="activeSuccess"
          @activeError="activeError"
        ></one-image>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        <el-button type="primary" @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import oneImage from "@/components/Upload/oneImage";
export default {
  name: "",
  components: { oneImage },
  props: {},
  data() {
    /**
     * @param {
     * 定义图片的校验
     * }
     */
    var verify = (rule, value, callback) => {
      // 先判断照片是否已经上传完成
      if (!this.form.url) {
        //照片没有上传或正在上传中
        if (this.accomplish) {
          //如果为true证明照片正在上传中
          callback(new Error("照片正在上传中,请等待上传完成!"));
        } else {
          // 反之则没有点击上传照片
          callback(new Error("请上传照片!"));
        }
      } else {
        //url里已经有值,照片已经上传完成
        callback();
      }
    };
    return {
      /**
       * @param {
       *当子组件上传成功,父组件接收的url
       * }
       */

      form: {
        url: ""
      },
      formRules: {
        imgUrl: [
          {
            required: true,
            validator: verify
          }
        ]
      },
      /**
       * @param {
       *照片是否正处在上传进行中
       *false   |   不是或并未开始上传
       *true    |   照片正处在上传中
       * }
       */
      accomplish: false,
      /**
       * @param {
       *父组件通过改变hidden的值true/false
       *来更改子组件    +   号的显示与隐藏
       *false   |   显示
       *true    |   隐藏
       * }
       */
      hidden: false
    };
  },
  created() {},
  mounted() {},
  methods: {
    /**
     * @param {
     * 图片上传成功
     * }
     */
    activeSuccess(url) {
      this.form.url = url;
      this.hidden = true; //隐藏+号
      this.accomplish = false; //更改正在上传中这个状态
    },
    /**
     * @param {
     * 图片上传失败
     * }
     */
    activeError() {
      this.form.url = "";
      this.hidden = false;
      this.accomplish = false;
    },
    /**
     * @param {
     *文件正在上传中的状态
     *1.):  上传中!
     *上传中需要设置  +   为隐藏
     * }
     */
    updataState(v) {
      this.hidden = v;
      this.accomplish = v;
    },
    /**
     * @param {
     *子组件上传图片,通过此钩子函数向父组件传达
     *1.):   删除图片!
     *删除图片需要设置   +   为显示
     *删除图片需要清空url地址
     * }
     */
    activeRemove() {
      this.hidden = false;
      this.form.url = "";
      this.accomplish = false;
    },
    /**
     * @param {
     * 提交上传的url
     * }
     */

    submitForm(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          alert("submit!");
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.activeRemove();
      this.$refs.oneImage.resetUpload();
      this.$refs[formName].resetFields();
    }
  },
  computed: {}
};
</script>
<style lang='scss' scoped>
.img-box {
  width: 600px;
  height: 600px;
  margin: 20px auto;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值