问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

vue的cropperjs,在安卓手机跟电脑浏览器都可以拖动裁剪,在苹果手机上...

发布网友 发布时间:2022-04-23 22:24

我来回答

2个回答

懂视网 时间:2022-05-14 22:55

在router里面放置参数,然后通过调用route.params.xxx或者route.query.xxx进行获取

通过props进行通信

这里我们使用eventBus进行组件之间的通信

步骤

1.声明一个bus组件用于B组件把参数传递给A组件

//bus.js
import Vue from 'vue'; 
export default new Vue();

2.在A组件中引用bus组件,并实时监听其参数变化

// A.vue
import Bus from '../../components/bus/bus.js'
export default {
 components: { Bus },
 data () {},
 created: function () {
 Bus.$on('getTarget', imgToken => { 
 var _this = this;
 console.log(imgToken);
 ... 
 }); 
 }
}

3.B组件中同样引用bus组件,来把参数传给A组件

// B.vue
// 传参
Bus.$emit('getTarget', imgToken);

参考:

vue-$on
vue-$emit
vue.js之路(4)——vue2.0s中eventBus实现兄弟组件通信

vue选图截图插件完整代码

<template>
 <p class="myCropper-container">
 <p id="myCropper-workspace">
 <p class="myCropper-words" v-show="!imgCropperData.imgSrc">请点击按钮选择图片进行裁剪</p>
 </p>
 <p class="myCropper-preview" :class="isShort ? 'myCropper-preview-short' : 'myCropper-preview-long'">
 <p class="myCropper-preview-1 avatar-preview">
 ![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
 </p>
 <p class="myCropper-preview-2 avatar-preview">
 ![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
 </p>
 <p class="myCropper-preview-3 avatar-preview">
 ![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
 </p>
 <input id="myCropper-input" type="file" :accept="imgCropperData.accept" ref="inputer" @change="handleFile">
 <Button type="ghost" class="myCropper-btn" @click="btnClick">选择图片</Button>
 <Button type="primary" class="myCropper-btn" :loading="cropperLoading" @click="crop_ok">确认</Button>
 </p>
 </p>
</template>
<script>
 var ezjsUtil = Vue.ezjsUtil;
 import Bus from './bus/bus.js' 
 export default {
 components: { Bus },
 props: {
 imgType: {
 type: String
 },
 proportionX: {
 type: Number
 },
 proportionY: {
 type: Number
 }
 },
 data () {
 return {
 imgCropperData: {
 accept: 'image/gif, image/jpeg, image/png, image/bmp',
 maxSize: 5242880,
 file: null, //上传的文件
 imgSrc: '', //读取的img文件base64数据流
 imgUploadSrc: '', //裁剪之后的img文件base64数据流
 },
 imgObj: null,
 hasSelectImg: false,
 cropperLoading: false,
 isShort: false,
 }
 },
 created: function () {
 let _this = this;
 },
 mounted: function () {
 let _this = this;
 // 初始化预览区域
 let maxWidthNum = Math.floor(300 / _this.proportionX);
 let previewWidth = maxWidthNum * _this.proportionX;
 let previewHeight = maxWidthNum * _this.proportionY;
 if (previewWidth / previewHeight <= 1.7) {
 previewWidth = previewWidth / 2;
 previewHeight = previewHeight / 2;
 _this.isShort = true;
 }
 // 设置最大预览容器的宽高
 $('.myCropper-preview-1').css('width', previewWidth + 'px');
 $('.myCropper-preview-1').css('height', previewHeight + 'px');
 // 设置中等预览容器的宽高
 $('.myCropper-container .myCropper-preview .myCropper-preview-2').css('width',( previewWidth / 2) + 'px');
 $('.myCropper-container .myCropper-preview .myCropper-preview-2').css('height', (previewHeight / 2) + 'px');
 // 设置最小预览容器的宽高
 $('.myCropper-container .myCropper-preview .myCropper-preview-3').css('width',( previewWidth / 4) + 'px');
 $('.myCropper-container .myCropper-preview .myCropper-preview-3').css('height', (previewHeight / 4) + 'px');
 },
 methods: {
 // 点击选择图片
 btnClick () {
 let _this = this;
 // 模拟input点击选择文件
 document.getElementById('myCropper-input').click();
 },
 // 选择之后的回调
 handleFile (e) {
 let _this = this;
 let inputDOM = this.$refs.inputer;
 // 通过DOM取文件数据
 _this.file = inputDOM.files[0];
 // 判断文件格式
 if (_this.imgCropperData.accept.indexOf(_this.file.type) == -1) {
 _this.$Modal.error({
 title: '格式错误',
 content: '您选择的图片格式不正确!'
 });
 return;
 }
 // 判断文件大小限制
 if (_this.file.size > 5242880) {
 _this.$Modal.error({
 title: '超出限制',
 content: '您选择的图片过大,请选择5MB以内的图片!'
 });
 return;
 }
 var reader = new FileReader();
 // 将图片将转成 base64 格式
 reader.readAsDataURL(_this.file);
 reader.onload = function () {
 _this.imgCropperData.imgSrc = this.result;
 _this.initCropper();
 }
 },
 // 初始化剪切
 initCropper () {
 let _this = this;
 // 初始化裁剪区域
 _this.imgObj = $('![](' + _this.imgCropperData.imgSrc + ')');
 let $avatarPreview = $('.avatar-preview');
 $('#myCropper-workspace').empty().html(_this.imgObj);
 _this.imgObj.cropper({
 aspectRatio: _this.proportionX / _this.proportionY,
 preview: $avatarPreview,
 crop: function(e) {
 }
 });
 _this.hasSelectImg = true;
 },
 // 确认
 crop_ok () {
 let _this = this, imgToken = null, imgBase64Data = null;
 // 判断是否选择图片
 if (_this.hasSelectImg == false) {
 _this.$Modal.error({
 title: '裁剪失败',
 content: '请选择图片,然后进行裁剪操作!'
 });
 return false;
 }
 // 确认按钮不可用
 _this.cropperLoading = true;
 let $imgData = _this.imgObj.cropper('getCroppedCanvas')
 imgBase64Data = $imgData.toDataURL('image/png'); 
 // 构造上传图片的数据
 let formData = new FormData();
 // 截取字符串
 let photoType = imgBase64Data.substring(imgBase64Data.indexOf(",") + 1);
 //进制转换
 const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
 const byteCharacters = atob(b64Data);
 const byteArrays = [];
 for(let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
 const slice = byteCharacters.slice(offset, offset + sliceSize);
 const byteNumbers = new Array(slice.length);
 for(let i = 0; i < slice.length; i++) {
 byteNumbers[i] = slice.charCodeAt(i);
 }
 const byteArray = new Uint8Array(byteNumbers);
 byteArrays.push(byteArray);
 }
 const blob = new Blob(byteArrays, {
 type: contentType
 });
 return blob;
 }
 const contentType = 'image/jepg';
 const b64Data2 = photoType;
 const blob = b64toBlob(b64Data2, contentType);
 formData.append("file", blob, "client-camera-photo.png")
 formData.append("type", _this.imgType)
 // ajax上传
 $.ajax({
 url: _this.$nfs.uploadUrl,
 method: 'POST',
 data: formData,
 // 默认为true,设为false后直到ajax请求结束(调完回掉函数)后才会执行$.ajax(...)后面的代码
 async: false,
 // 下面三个,因为直接使用FormData作为数据,contentType会自动设置,也不需要jquery做进一步的数据处理(序列化)。
 cache: false,
 contentType: false,
 processData: false,
 type: _this.imgType,
 success: function(res) {
 let imgToken = res.data.token;
 _this.cropperLoading = false;
 // 传参
 Bus.$emit('getTarget', imgToken); 
 },
 error: function(error) {
 _this.cropperLoading = false;
 _this.$Modal.error({
 title: '系统错误',
 content: '请重新裁剪图片进行上传!'
 });
 }
 });
 },
 }
 }
</script>
<style lang="less" scoped>
 .myCropper-container {
 height: 400px;
 }
 .myCropper-container #myCropper-input {
 width: 0px;
 height: 0px;
 }
 .myCropper-container #myCropper-workspace {
 width: 500px;
 height: 400px;
 border: 1px solid #dddee1;
 float: left;
 }
 // 裁剪图片未选择图片的提示文字
 .myCropper-container #myCropper-workspace .myCropper-words{
 text-align: center;
 font-size: 18px;
 padding-top: 180px;
 }
 // 裁剪图片的预览区域
 .myCropper-container .myCropper-preview-long {
 width: 300px;
 }
 .myCropper-container .myCropper-preview-short {
 width: 200px;
 }
 .myCropper-container .myCropper-preview {
 float: left;
 height: 400px;
 margin-left: 10px;
 }
 .myCropper-container .myCropper-preview .myCropper-preview-1 {
 border-radius: 5px;
 overflow: hidden;
 border: 1px solid #dddee1;
 box-shadow: 3px 3px 3px #dddee1;
 img {
 width: 100%;
 height: 100%;
 }
 }
 .myCropper-container .myCropper-preview .myCropper-preview-2 {
 margin-top: 20px;
 border-radius: 5px;
 overflow: hidden;
 border: 1px solid #dddee1;
 box-shadow: 3px 3px 3px #dddee1;
 img {
 width: 100%;
 height: 100%;
 }
 }
 .myCropper-container .myCropper-preview .myCropper-preview-3 {
 margin-top: 20px;
 border-radius: 5px;
 overflow: hidden;
 border: 1px solid #dddee1;
 box-shadow: 3px 3px 3px #dddee1;
 img {
 width: 100%;
 height: 100%;
 }
 }
 // 按钮
 .myCropper-btn {
 float: left;
 margin-top: 20px;
 margin-right: 10px;
 }
</style>

热心网友 时间:2022-05-14 20:03

手机不支持
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
灵显的意思是什么 安国药王庙结构 显灵宫建筑构造 煤炭储量储量计算 大容量塑料水杯可以用开水烫吗 大容量塑料水杯能不能用开水烫 辽宁朝阳一日游去哪里比较好 ...电脑打开后出现一个对话框影响正常开机不知道怎样解决 哪些可以关掉,这些英文是什么意思? 企业应对网络舆情攻略:10个危机公关应对策略,有效解决 兔宝宝石氏名字寓意好字 Ant Design of Vue的通知提醒框的内容怎么改成自己写的组件(Vue文件)啊... 每年春节家家户户为什么要贴春联? 过年为何要贴对联呢?都有哪些寓意? 过年为什么要贴春联? 有哪一款洁面乳比较好用呀? 微响泉兮氨基酸洗面奶和温净氨基酸洗面奶哪个好?有啥区别?油性皮肤,偶尔... 什么牌子的洗面奶好用 洗面奶哪个最好用 现在市面上什么牌子的洗面奶好呢? 氨基酸的洗面乳好用吗? 美白效果最好的洗面奶是哪一款,你是怎么认为的呢? 温净氨基酸洗面奶和芙丽芳丝氨基酸洗面奶哪个好 如何用vue实现模态框组件 Vue.js input 在手机上却可以正常输入字母, PDA工具 不能输入字母,只能... vue前端谷歌测试正常,手机端不能滑动怎么办(安卓,苹果都不能滑动... react-native和vue哪个适合移动端 Vue第一节:Vue.js框架是什么,为什么选择它 构树上红彤彤的果子可以食用吗,有什么功效? 构树上涨的这种东西是什么,能食用吗? 专家说构树浑身是宝,用途有很多,为啥不少农民却很讨厌构树? 求前端大神帮忙,vue项目,修改了index.js ,的host:&#39;192.168.1.101... fl怎么从汉化版变回英文版 会声会影里面视频大小比例如何调整 pr视频比例如何调整 《黑暗料理王》凉拌凉粉配方汇总 我一个人走慢点也没关系是什么意思 只要是对的人,迟一点,慢一点,晚一点也没关系? 道路且长来日可期,脚步慢一点也无妨是什么意思? 在等等慢一点也无妨是什么意思 只要在变好慢一点又何妨的诗句 把事情做好,慢点没关系,是什么意思? 只要在变好,慢一点也无妨,希望我们都是“苦尽甘来的人”什么意思? 我在餐馆上班,老板说厨师,要好好炒菜,动作慢一点都没关系,不要炒的乱七八糟的,厨师说要想把菜炒好? DNF赚钱攻略,不求快只求能赚钱,慢一点也没关系 求了,答对必采,慢一点没关系的 就叫凡凡&#127800;:+只要在变好+慢一点没关系+希望我们都是“苦尽甘来的人”怎么回? 孩子写作业很慢咋办 只要在变好,慢一点也无妨,希望我们都是“苦尽甘来的人”什么意思 请问一日三餐这样吃可以减肥吗?稍微慢一点都没关系。 关你屁事关我屁事还有一句是什么