//HTML cropper.js 文档地址: https://github.com/fengyuanchen/cropperjs/blob/master/README.md
<template>
<div class="container">
<div>
<el-button size="small" plain icon="el-icon-plus" @click="uploadFuc"
>点击上传</el-button
>
</div>
<!-- <loading v-if="loadingFlag"></loading> -->
<div class="defaultimg" v-if="!imgurl && isShowdefault">默认图</div>
<div class="coropperImg" v-if="listImg" :style="styleObject">
<img :src="listImg" :width="imgWidth" :height="imgHeight" />
<span @click="deleteImg" v-if="isShowDelete">✕</span>
</div>
<div class="upload-file">
<el-dialog
:visible.sync="dialogTableVisible"
:title="title"
:modal-append-to-body="false"
:width="dialogWidth"
>
<div class="img-box">
<div class="upload-box" :style="styleObject">
<div class="upload">
<div v-if="!imgurl" class="upFileStyle">
<el-button
size="small"
@click="addFile"
plain
icon="el-icon-plus"
>点击上传</el-button
>
<div slot="tip" class="el-upload__tip">{{ tips }}</div>
<input
type="file"
style="display:none"
ref="file"
accept="image/*"
@change="getFile($event)"
/>
</div>
<img
v-if="imgurl"
:id="imageId"
:src="imgurl"
class="avatarImg"
/>
</div>
<div
v-if="imgurl"
:class="['caropper', isDisable == true ? 'disabled' : '']"
>
<div
@click="addFile"
:class="['repeat-img', isDisable == true ? 'disabled' : '']"
>
重新上传
</div>
<input
type="file"
style="display:none"
ref="file"
accept="image/*"
@change="getFile($event)"
/>
<div class="icon-font">
<div class="icon icon-jianqu" @click="narrowImg" />
<div class="icon icon-zengjia" @click="enlargeImg" />
<div class="icon icon-shuaxin" @click="refresh" />
</div>
</div>
</div> <div class="imgPrew" :style="stylePrew">
<div v-if="imgurl" class="prewImg" />
<img v-else src alt />
<h5>预览</h5>
<div />
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="small" plain @click="dialogVisibleCancel"
>取 消</el-button
>
<el-button
size="small"
plain
:class="['sure', imgurl ? '' : 'disabled']"
@click="confirm"
:loading="loadingFlag"
>确 定</el-button
>
</div>
</el-dialog>
</div>
</div>
</template> //JS
<script>
export default {
props: {
title: {
type: String,
required: false,
default: () => {
return "";
}
},
imageId: {
type: String,
required: false,
default: () => {
return "";
}
},
listImgParent: {
type: String,
required: false,
default: () => {
return "";
}
},
dialogWidth: {
type: String,
required: false,
default: () => {
return "";
}
},
contentType: {
type: String,
required: false,
default: () => {
return "";
}
},
tips: {
type: String,
required: false,
default: () => {
return "";
}
},
proportion: {
type: Number,
required: false,
default: () => {
return "";
}
},
imgWidth: {
type: String,
required: false,
default: () => {
return "";
}
},
imgHeight: {
type: String,
required: false,
default: () => {
return "";
}
},
prewWidth: {
type: String,
required: false,
default: () => {
return "";
}
},
prewHeight: {
type: String,
required: false,
default: () => {
return "";
}
},
sizeTips: {
type: String,
required: false,
default: () => {
return "图片大小不超1M";
}
},
fileSize: {
type: Number,
required: false,
default: () => {
return 1048576;
}
},
isShowdefault: {
type: Boolean,
required: false,
default: () => {
return false;
}
},
isShowDelete: {
type: Boolean,
required: false,
default: () => {
return false;
}
}
},
data() {
return {
dialogTableVisible: false,
imgurl: "",
uploadUrl: null,
listImg: "",
carImage: "",
styleObject: {
width: this.imgWidth,
height: this.imgHeight
},
stylePrew: {
width: this.prewWidth,
height: this.prewHeight
},
fileName: "",
loadingFlag: false,
isDisable: false
};
},
created() {
this.loadImgSrc();
},
mounted() {
//详情页面图片展示
if (this.listImgParent) {
this.listImg = this.listImgParent;
this.$emit("listentoChild", this.listImgParent);
}
},
methods: {
//删除图片按钮
deleteImg() {
this.listImg = "";
this.$emit("listentoChild", this.listImg);
},
//动态插入Croppe. js 插件,做图片裁剪
loadImgSrc() {
if (!document.getElementById("IMAGE_LINK_ID")) {
let linkImage = document.createElement("link");
linkImage.id = "IMAGE_LINK_ID";
linkImage.type = "text/css";
linkImage.rel = "stylesheet";
linkImage.href =
"//cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.min.css";
linkImage.onload = () => {
let scriptImage = document.createElement("script");
scriptImage.id = "IMAGE_SCRIPT_ID";
scriptImage.type = "text/javascript";
scriptImage.src =
"//cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.min.js";
document.body.appendChild(scriptImage);
};
document.head.appendChild(linkImage);
}
},
//添加图片上传
addFile() {
this.$refs.file.click();
},
//获取裁剪完成后url
getFile(event) {
if (this.carImage) {
this.carImage.destroy();
}
this.file = event.target.files[0];
const item = {
name: this.file.name,
size: this.file.size,
file: this.file
};
this.html5Reader(this.file, item);
this.f = item;
},
// 将图片文件转成BASE64格式
html5Reader(file, item) {
let fileName = item.name
.toLowerCase()
.split(".")
.splice(-1);
this.fileName = fileName.join("");
const isJPG = file.type == "image/jpeg";
const isPNG = file.type == "image/png";
const isLt1M = file.size > this.fileSize;
if (!isJPG && !isPNG) {
this.$message.error("上传图片只能是 JPG 格式 或 png 格式!");
if (this.imgurl) {
this.cuttingImg();
}
return false;
}
if (isLt1M) {
this.$message.error(this.sizeTips);
if (this.imgurl) {
this.cuttingImg();
}
return false;
}
let _this = this;
const reader = new FileReader();
reader.onload = e => {
_this.imgurl = e.target.result;
};
reader.readAsDataURL(file);
this.$nextTick(() => {
setTimeout(() => {
this.cuttingImg();
}, 1000);
});
},
//裁剪图片确定上传
confirm() {
this.loadingFlag = true;
this.isDisable = true;
let cas = null;
setTimeout(() => {
cas = this.carImage.getCroppedCanvas().toDataURL("image/jpeg");
let formData = new FormData();
let uploadData = {
contentType: this.contentType,
project: "hooli"
};
Object.assign(uploadData, this.$net.commonParams());
uploadData.signToken = this.$net.paramsSign(
uploadData,
this.$apis.api_common_files
);
for (let key in uploadData) {
formData.append(key, uploadData[key]);
}
let file = this.dataURLtoFile(cas, `imageName.${this.fileName}`);
formData.append("files[]", file);
axios
.post(this.$apis.api_common_files, formData, {
"Content-Type": "multipart/form-data"
})
.then(
res => {
this.loadingFlag = false;
this.isDisable = false;
let data = res.data;
if (parseInt(data.code) == 0) {
let imgUrl = data.data.host + data.data.url;
this.listImg = imgUrl;
this.dialogTableVisible = false;
this.$emit("listentoChild", imgUrl);
}
},
e => {
this.loadingFlag = false;
e && e.msg
? this.$message.error(e && e.msg)
: this.$message.error("上传超时,请压缩图片后重试。");
}
);
}, 100);
},
//将base64转换为文件
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
},
dialogVisibleCancel() {
this.loadingFlag = false;
this.dialogTableVisible = false;
},
uploadFuc() {
this.dialogTableVisible = true;
this.imgurl = "";
if (this.carImage) {
this.carImage.destroy();
}
},
cuttingImg() {
let image = document.getElementById(this.imageId);
this.carImage = new Cropper(image, {
aspectRatio: this.proportion,
viewMode: 1,
crop() {},
preview: ".prewImg"
});
},
refresh() {
this.carImage.reset();
},
narrowImg() {
this.carImage.zoom(-0.1);
},
enlargeImg() {
this.carImage.zoom(0.1);
}
}
};
</script>
//css
<style>
.container .el-dialog__header {
padding: 10px 0 10px 10px !important;
}
.container .avatar-uploader .el-upload {
border: 0;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.container .el-button.is-plain:focus,
.el-button.is-plain:hover {
background: rgba(255, 255, 255, 1);
border-radius: 4px;
border: 1px solid;
color: rgba(102, 102, 102, 1);
}
.container .el-upload__tip {
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(153, 153, 153, 1);
padding: 0 50px;
line-height: 23px;
}
.container .avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.container .avatarImg {
width: 270px;
height: 270px;
}
.container .dialog-footer button {
width: 120px;
height: 36px;
line-height: 36px;
background: rgba(249, 249, 249, 1);
border-radius: 4px;
border: 1px solid #cccccc;
padding: 0;
font-size: 14px;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(102, 102, 102, 1);
outline: none;
}
.container .dialog-footer .sure {
background: rgba(255, 82, 61, 1);
border-radius: 4px;
border: 0;
color: #fff;
margin-left: 10px;
}
.container .el-dialog {
width: 470px;
}
.container .el-dialog__footer {
border-top: 1px solid rgba(238, 238, 238, 1);
padding: 30px 0;
margin-top: 30px;
text-align: center;
}
.container .el-dialog__body {
padding: 40px 20px;
}
</style> <style lang="less" scoped>
.container {
.disabled {
pointer-events: none;
cursor: default;
opacity: 0.6;
}
.defaultimg {
font-size: 12px;
line-height: 12px;
margin: 24px 0 10px;
}
.coropperImg {
margin-top: 10px;
position: relative;
span {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
top: -27px;
right: -22px;
z-index: 10;
cursor: pointer;
}
}
#imageId {
width: 110px;
height: 100px;
}
.img-box {
display: flex;
justify-content: space-between;
.upload-box {
position: relative;
.upload {
border: 1px dashed #d9d9d9;
border-radius: 2px;
display: flex;
flex-direction: column;
overflow: hidden;
width: 100%;
height: 100%;
background: rgba(249, 249, 249, 1);
img {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.upFileStyle {
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
// display: flex;
// justify-content: center;
// align-items: center;
// flex-wrap: wrap;
}
}
}
.caropper {
display: flex;
justify-content: space-between;
padding-top: 10px;
.icon-font {
display: flex;
cursor: pointer;
.icon {
color: #999999;
margin-left: 20px;
font-size: 14px;
}
}
} .repeat-img {
font-size: 14px;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(255, 179, 85, 1);
cursor: pointer;
}
.imgPrew {
background: rgba(238, 238, 238, 1);
text-align: center;
margin-top: 40px;
.prewImg {
width: 100% !important;
height: 100% !important;
box-shadow: 15px 0px 55px 17px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
img {
width: 100%;
height: 100%;
}
h5 {
font-size: 14px;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(153, 153, 153, 1);
line-height: 20px;
}
}
}
}
</style>
 

图片裁剪 cropper.js 上传组件封装 vue的更多相关文章

  1. 图片裁剪(cropper)后上传问题

    最近工作需要处理头像裁剪以及上传,研究了几天,写点心得,提醒自己记住踩过的坑,能帮助别人当然更好. 功能基本就是这样: 这里需要注意的是:拿到需求后,不要急于直接上手,花费半个小时,甚至更长时间缕清整 ...

  2. 适应各浏览器图片裁剪无刷新上传jQuery插件(转)

    看到一篇兼容性很强的图片无刷新裁剪上传的帖子,感觉很棒.分享下!~ 废话不多说,上效果图. 一.首先建立如下的一个page <!DOCTYPE html> <html xmlns=& ...

  3. 封装react antd的upload上传组件

    上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等.至于为何要把上传组 ...

  4. AntDesign VUE:上传组件自定义限制的两种方式(Boolean、Promise)

    AntD上传组件 AntDesign VUE文档 第一种方式 beforeUpload(file) { let isLt = true if (filesSize) { isLt = file.siz ...

  5. 微信小程序简单封装图片上传组件

    微信小程序简单封装图片上传组件 希望自己 "day day up" -----小陶 我从哪里来 在写小程序的时候需要上传图片,个人觉得官方提供的 Uploader 组件不是太好用, ...

  6. vue图片上传组件

    前言:很多项目中都需要用到图片上传功能,而其多处使用的要求,为了避免重复造轮子,让我决定花费一些时间去深入了解,最终封装了一个vue的图片上传组件.现将总结再次,希望有帮助. Layout <d ...

  7. js插件---强大的图片裁剪Cropper

    js插件---强大的图片裁剪Cropper 一.总结 一句话总结:官网或者github里面的文档或者demo才是真的详细 使用的话找到图片裁剪后的base64数据,然后这个数据可下载可传递到服务器 1 ...

  8. JS组件系列——Bootstrap文件上传组件:bootstrap fileinput

    前言:之前的三篇介绍了下bootstrap table的一些常见用法,发现博主对这种扁平化的风格有点着迷了.前两天做一个excel导入的功能,前端使用原始的input type='file'这种标签, ...

  9. 图片上传组件webuploader

    前端组件webuploader 当时也是搞了很久参考这种demo,但是没记.现在事后大致总结下.直接上大概代码(我使用asp.net  MVC来做的): 执行顺序:(get)Record/Add——A ...

随机推荐

  1. 3.1.3 Spring之AOP

    三.Spring之AOP 1. 代理模式 (1) 什么是代理模式? 代理模式是面向对象编程的23种基础设计模式之一.为其他对象(代理对象)提供一种代理以控制对这个对象(源对象)的访问. 就是说,声明一 ...

  2. Pubmed/PMC/Meline的异同点【转载】

    转自:http://paper.dxy.cn/article/495034 一.PubMed.PMC 和 MEDLINE 到底有什么区别和联系? 可以看出,PubMed的收录范围是最广的:三个都是生物 ...

  3. Py之any函数【转载】

    转自:http://www.runoob.com/python/python-func-any.html 1.any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 ...

  4. phpstorm----------phpstorm如何安装和使用laravel plugin

    1.安装 2.安装成功以后,删除项目里面的.idea文件.然后关闭phpstrom,重新打开该项目,就会提示你 然后.idea里面就会生成 laravel-plugin.xml 文件.就可以使用直接C ...

  5. Centos7 update dotnet 无法识别

    使用了yum update 后 原来好好的dotnet 用不了了 /usr/bin/dotnet 找不到 卸载重装都没法了.... 解决方法: 把dotnet 拷贝到 /usr/bin 下面去就好了 ...

  6. Centos7 安装redis

    1.下载redis安装包 wget http://download.redis.io/releases/redis-4.0.9.tar.gz 2.检查及下载gcc gcc -v yum -y inst ...

  7. P1342 请柬

    最近一直在做最短路......所以今天就再做一道最短路吧.... 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片 ...

  8. 用Nuget部署程序包

    用Nuget部署程序包 Nuget是.NET程序包管理工具(类似linux下的npm等),程序员可直接用简单的命令行(或VS)下载包.好处: (1)避免类库版本不一致带来的问题.GitHub是管理源代 ...

  9. IDEA SpringBoot 打包(jar)

    项目结构: sf-xxx-api sf-xxx-domain sf-xxx-common sf-xxx-web (web模块) 期望输出结果目录 bin/server.sh libs/**.jar,* ...

  10. CLASS 类 __getattr__

    class Chain(object): def __init__(self, path=''): self._path = path def __getattr__(self, path): ret ...