公司項目作一個更換logo的功能,要求能夠自定義裁剪圖片,vueCopper能夠實現,直接拿過來用,下面記錄一下使用過程當中的問題。vue
首先安裝依賴:ajax
npm install vue-cropper@0.3.6複製代碼
這裏注意一下,我開始是直接安裝的npm install vue-cropper,而後出現報錯:npm
好像是版本問題,而後查了一下 直接安裝低版本的,好了api
而後組件封裝上代碼:bash
<template>
<div class="qn-copper">
<div class="copper-contain">
<div class="copper-contain-left">
<vueCropper :img="option.img"
:canMoveBox='option.canMoveBox'
:centerBox='option.centerBox'
ref="cropper"
:original='option.original'
:outputSize="option.size"
:outputType="option.outputType"
:info="option.info"
:infoTrue='option.infoTrue'
:canScale="option.canScale"
:autoCrop="option.autoCrop"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropHeight"
:fixed="option.fixed"
:fixedBox="option.fixedBox"
:fixedNumber="option.fixedNumber"
@realTime="realTime"
@imgLoad="imgLoad"
></VueCropper>
</div>
<div class="copper-contain-right">
<div class="show-preview">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
<div class="save-btn" @click="save">
保存
</div>
</div>
</div>
<div class="copper-operate">
<label class="font_color">
<span></span><span title='只容許上傳圖片或PDF'>上傳</span>
<input @change="upload_file($event,1)" type="file"
class="files" accept=".pdf,image/*">
</label>
<i class="el-icon-plus icon" @click='changeScale(1)'></i>
<i class="el-icon-minus icon" @click='changeScale(-1)'></i>
<i class="el-icon-refresh-left icon" @click='rotateLeft'></i>
<i class="el-icon-refresh-right icon" @click="rotateRight"></i>
</div>
</div>
</template>
<script>
import VueCropper from 'vue-cropper'
import {oss_config_get,
file_delete,
file_update} from '../../../api/common_api.js'
export default {
name:'qnCopper',
components:{
VueCropper,
},
props:{
update_methods:'',設置logo的接口名稱 由父組件傳入
update_data:{} 設置logo的接口數據格式
},
data(){
return{
option: {
img: "/api/oss/proxy/logo/QQ圖片20191030222607.jpg", // 裁剪圖片的地址
info: true, // 裁剪框的大小信息
size: 1,
outputSize: 0.8, // 裁剪生成圖片的質量
outputType: "png",// 裁剪生成圖片的格式
canScale: true, // 圖片是否容許滾輪縮放
autoCrop: true, // 是否默認生成截圖框
canMoveBox: true, // 截圖框可否拖動
// 只有自動截圖開啓 寬度高度才生效
autoCropWidth: 300, // 默認生成截圖框寬度
autoCropHeight: 300, // 默認生成截圖框高度
// 開啓寬度和高度比例
fixed: true, // 是否開啓截圖框寬高固定比例
fixedBox: true, // 固定截圖框大小 不容許改變
fixedNumber: [1, 1],// 截圖框的寬高比例
original: false, // 上傳圖片按照原始比例渲染
centerBox: true, // 截圖框是否被限制在圖片裏面
infoTrue: true // true 爲展現真實輸出圖片寬高 false 展現看到的截圖框寬高
},
previews: {},
ossConfig:'',
fileName:'', upkey:'',
}
},
created(){
this.config_init();
},
methods:{
//阿里雲文件上傳服務初始化,不須要的不用
config_init(){
let timeStamp = Date.parse(new Date())/1000;
// console.log(this.$store.state.ossConfig,'000000',timeStamp)
if(timeStamp-this.$store.state.ossConfig.expire<60*60*24){
this.ossConfig = this.$store.state.ossConfig;
}else{
this.ossConfig = oss_config_get();
}
},
upload_file(e,num){
let _this = this;
//上傳圖片
let file = e.target.files[0]
_this.fileName = file.name;
if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
this.$message({
message: '圖片類型必須是.gif,jpeg,jpg,png,bmp中的一種',
type: 'warning'
});
return false
}
let reader = new FileReader();
reader.onload =(e) => {
let data;
if (typeof e.target.result === 'object') {
// 把Array Buffer轉化爲blob 若是是base64不須要
data = window.URL.createObjectURL(new Blob([e.target.result]))
} else {
data = e.target.result
}
if (num === 1) {
_this.option.img = data
}
}
// 轉化爲base64
// reader.readAsDataURL(file)
// 轉化爲blob
reader.readAsArrayBuffer(file);
},
// 實時預覽函數
realTime(data){
this.previews = data
},
imgLoad(msg){
console.log(msg)
},
//放大/縮小
changeScale(num) {
console.log('changeScale')
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//坐旋轉
rotateLeft() {
console.log('rotateLeft')
this.$refs.cropper.rotateLeft();
},
//右旋轉
rotateRight() {
console.log('rotateRight')
this.$refs.cropper.rotateRight();
},
保存 先上傳到文件服務器 而後調用設置logo接口
save(){
let vue = this;
let formData = new FormData();
this.$refs.cropper.getCropBlob((data) => {
console.log(data)
let img = window.URL.createObjectURL(data)
console.log(img,'img')
let xmlhttp = new XMLHttpRequest();
formData.append('file', data,this.fileName);
let name = 'logo/' + (new Date()).valueOf();
formData.append('key', name);
for(let i in this.ossConfig){
formData.append(i,this.ossConfig[i])
}
xmlhttp.open("POST", '/api/oss/proxy' , true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
let result = JSON.parse(xmlhttp.response);
if(result.code=='1'){
vue.update_parent(result.data.file)
}
} else {
vue.$message({message:'上傳錯誤',type:'error'});
}
}
}
xmlhttp.upload.onprogress = function (event) {
}
xmlhttp.upload.onloadstart = function () {
};
xmlhttp.upload.onloadend = function () {
};
xmlhttp.onerror = function () {
vue.list_show();
};
xmlhttp.send(formData);
})
},
設置logo接口
update_parent(url){
this.update_data.logoPic = url;
this.update_methods(this.update_data).then(res=>{
if(res.code == 1){
this.$message({message:'修改爲功',type:'success'});
}
}).catch(err=>{
console.log('ajax_err:',err)
})
}
}}
</script>
<style lang="less" scoped>
.monitor-system{
.qn-copper{
}
}
.fireUnit-system{
.qn-copper{
}
}
.fireSupUnit-system{
//第三套央視
.qn-copper{
.font_color{
color:#5E9BBA;
}
}
}
.qn-copper{
width: 100%;
height: 100%;
.copper-contain{
width: 100%;
height: 80%;
display: flex;
.copper-contain-left{
width: 80%;
}
.copper-contain-right{
margin-left: 30px;
.show-preview{
width: 150px;
height: 150px;
overflow: hidden;
}
.save-btn{
margin-top:20px;
color:#24bbee;
cursor: pointer;
font-size: 15px;
}
}
}
.copper-operate{
color:#24bbee;
margin-top: 10px;
font-size: 15px;
text-align: left;
padding-left: 40px;
box-sizing: border-box;
.font_color{
cursor: pointer;
color:#24bbee;
margin:0 20px;
}
.files{
display: none;
}
.icon{
margin:0 20px;
font-size: 15px;
cursor: pointer;
}
}
}
</style>複製代碼
效果以下:服務器
若有問題,歡迎探討,若是滿意,請手動點贊,謝謝!🙏
app