├── .DS_Store ├── .gitignore ├── README.md ├── _config.yml ├── dist └── vue-pic-clip.min.js ├── docs ├── example.bundle.js ├── img │ ├── 1.aca4e29.jpg │ └── 2.9e7170f.jpg ├── index.html └── main.bundle.js ├── example ├── app.vue ├── home.vue ├── img │ ├── 1.jpg │ └── 2.jpg ├── main.js ├── router │ └── index.js ├── upload.vue ├── upload2.vue └── upload3.vue ├── index.html ├── package-lock.json ├── package.json ├── src ├── index.js └── vue-clip.vue ├── webpack.config.js └── webpack.prod.conf.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tianyazz/vue-pic-clip/ddc4eed672bc0c0d87a9cb88ef79191993c5742d/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## vue-pic-clip 2 | ### 一个简单的移动端裁剪图片上传插件 3 | 4 | [预览demo](https://tianyazz.github.io/vue-pic-clip/docs/#/). 5 | 6 | ```markdown 7 | 8 | ### 安装 Install 9 | npm install vue-pic-clip -D 10 | 11 | // 组件内使用 12 | import { VueClip } from 'vue-pic-clip' 13 | components: { 14 | VueClip, 15 | }, 16 | 17 | // main.js里面使用 18 | import VueClip from 'vue-pic-clip' 19 | 20 | Vue.use(VueClip) 21 | 22 | ``` 23 | ```markdown 24 | 上传头像 30 | 31 | ``` 32 | 33 | ***** 34 | ### 配置参数 35 | 36 | 名称|功能|默认值|可选值 37 | ---|:--:|:--:|---: 38 | img|默认图片地址|空|url地址||base64||blob 39 | accept|上传图片类型|'image/png, image/jpeg, image/jpg, image/gif'|jpeg||png||gif等 40 | autoClip|是否生成截图框|false|ture||false 41 | autoClipWidth|截图框的宽度|容器宽度80%|0~容器宽度 42 | autoClipHeight|截图框的高度|与宽度相等|0~容器宽度 43 | canMove|图片能否拖动|true|true||fasle 44 | canMoveBox|截图框能否拖动|ture|ture||false 45 | dataUrlType|输出图片数据类型|blob|base64||blob 46 | fixed|截图框是否开启固定宽高比|false|true||false(若设置的宽高比例与宽高比不匹配,则按照宽高比计算高度) 47 | fixedNumber|截图框宽高比|[1,1]|[宽度,高度] 48 | fixedBox|固定截图框大小|false|true||false 49 | isOriginalImg|是否上传原图|false|true||false(启用裁剪时无效) 50 | maxWidth|生成图片的最大宽度|600|0~max(启用裁剪或上传原图时最大宽度无效) 51 | maxHeight|生成图片的最大高度|600|0~max(同上) 52 | outputSize|输出图片压缩比|1|0.1-1 53 | outputType|生成图片的格式|jpeg|jpeg||png||webp 54 | theme|样式风格|rect|rect||circle 55 | finish|完成操作事件||回调函数 56 | **** 57 | 58 | 主要研究[vue-cropper](https://github.com/xyxiao001/vue-cropper)的源码开发学习。一直使用这个插件做项目,最近比较闲,就撸了一个更简单的适合我自己用的插件。没有大量真机测试过,有什么问题,欢迎大家提Issues给我。 59 | 60 | ### 写个插件玩玩,给个star,多多支持,谢谢 61 | 62 | ### Thanks to 63 | - [JS中图片压缩的方法小结](https://www.jb51.net/article/128189.htm) 64 | - [vue-cropper](https://github.com/xyxiao001/vue-cropper) 65 | - [js获取图片EXIF, 解决图片旋转](https://www.cnblogs.com/suyuanli/p/8168407.html) 66 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-architect -------------------------------------------------------------------------------- /dist/vue-pic-clip.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("Vue-pic-clip",[],e):"object"==typeof exports?exports["Vue-pic-clip"]=e():t["Vue-pic-clip"]=e()}(window,function(){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,i),o.l=!0,o.exports}return i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)i.d(n,o,function(e){return t[e]}.bind(null,o));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=6)}([function(t,e,i){var n=i(2);"string"==typeof n&&(n=[[t.i,n,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};i(4)(n,o);n.locals&&(t.exports=n.locals)},function(t,e,i){"use strict";var n=i(0);i.n(n).a},function(t,e,i){(t.exports=i(3)(!1)).push([t.i,"\n@font-face {\n font-family: 'iconfont'; /* project id 953300 */\n src: url('//at.alicdn.com/t/font_953300_clegio409me.eot');\n src: url('//at.alicdn.com/t/font_953300_clegio409me.eot?#iefix') format('embedded-opentype'),\n url('//at.alicdn.com/t/font_953300_clegio409me.woff') format('woff'),\n url('//at.alicdn.com/t/font_953300_clegio409me.ttf') format('truetype'),\n url('//at.alicdn.com/t/font_953300_clegio409me.svg#iconfont') format('svg');\n}\n.clip[data-v-29874490] {\n position: relative;\n width: 100%;\n height: 100%;\n}\n.clip .icon[data-v-29874490],\n.clip > input[data-v-29874490] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 10;\n}\n.clip .picture[data-v-29874490] {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n -webkit-justify-content: center;\n justify-content: center;\n position: absolute;\n top: 0;\n right: 0;\n width: 100%;\n height: 100%;\n z-index: 20;\n}\n.clip .picture img[data-v-29874490] {\n max-width: 100%;\n max-height: 100%;\n}\n.clip > input[data-v-29874490] {\n width: 100%;\n opacity: 0;\n z-index: 30;\n}\n.clip .icon[data-v-29874490] {\n text-align: center;\n border: 2px solid rgba(0, 0, 0, .1);\n}\n.clip .icon i[data-v-29874490] {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n -webkit-justify-content: center;\n justify-content: center;\n height: 100%;\n}\n.clip .icon i[data-v-29874490]:before {\n content: \"\\E641\";\n display: block;\n font-size: 30px;\n font-family: \"iconfont\";\n line-height: 100%;\n color: rgba(0, 0, 0, .1);\n}\n.clip .msg[data-v-29874490] {\n position: fixed;\n top: 50%;\n left: 50%;\n z-index: 30;\n padding: 5px 20px;\n border-radius: 5px;\n -webkit-border-radius: 5px;\n transform: translate(-50%, -50%);\n -webkit-transform: translate(-50%, -50%);\n color: #fff;\n text-align: center;\n background: rgba(0, 0, 0, .7);\n}\n.rect .icon i[data-v-29874490] {\n height: 80%;\n}\n.rect .icon i[data-v-29874490]:before {\n content: \"\\E641\";\n line-height: 42px;\n}\n.rect p[data-v-29874490] {\n margin-top: -8px;\n font-size: 12px;\n color: #666;\n text-align: center;\n}\n.circle .icon[data-v-29874490],\n.circle .picture[data-v-29874490] {\n border-radius: 50%;\n -webkit-border-radius: 50%;\n}\n.circle .picture[data-v-29874490] {\n overflow: hidden;\n}\n.circle .icon i[data-v-29874490]:before {\n content: \"\\E6DA\";\n font-size: 30px;\n}\n.popup[data-v-29874490] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 20181211;\n background: rgba(0, 0, 0, .7);\n}\n.popup .button[data-v-29874490] {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n -webkit-justify-content: center;\n justify-content: center;\n position: absolute;\n bottom: 0;\n left: 0;\n z-index: 20;\n width: 100%;\n height: 48px;\n text-align: center;\n background: rgba(255, 255, 255, 1);\n}\n.popup button[data-v-29874490] {\n -webkit-tap-highlight-color: transparent;\n outline: none;\n display: inline-block;\n width: 40%;\n height: 38px;\n margin: 0 5%;\n border: 0;\n border-radius: 5px;\n color: #fff;\n background: rgba(50, 135, 255, .7);\n}\n.clip-popup[data-v-29874490] {\n background: none;\n}\n.clip-popup .clip-box[data-v-29874490],\n.clip-popup .clip-move[data-v-29874490],\n.clip-popup .popup-move[data-v-29874490] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n}\n.clip-popup .popup-move[data-v-29874490] {\n background: rgba(0, 0, 0, .5);\n z-index: 18;\n}\n.clip-popup .clip-box[data-v-29874490] {\n z-index: 20;\n}\n.clip-popup .clip-view[data-v-29874490] {\n display: block;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 1px solid rgba(50, 135, 255, 1.0);\n}\n.clip-popup .clip-move[data-v-29874490] {\n background: rgba(255, 255, 255, .1);\n z-index: 21;\n}\n.clip-popup .clip-info[data-v-29874490] {\n display: block;\n position: absolute;\n top: -26px;\n left: 12px;\n width: 112px;\n height: 25px;\n padding: 2px 5px;\n background: rgba(0, 0, 0, .8);\n color: #fff;\n}\n.clip-popup .clip-line[data-v-29874490] {\n position: absolute;\n display: block;\n width: 100%;\n height: 100%;\n z-index: 25;\n}\n.clip-popup .line-t[data-v-29874490] {\n top: -5px;\n height: 10px;\n}\n.clip-popup .line-r[data-v-29874490] {\n top: 0;\n right: -5px;\n width: 10px;\n}\n.clip-popup .line-b[data-v-29874490] {\n bottom: -5px;\n height: 10px;\n}\n.clip-popup .line-l[data-v-29874490] {\n top: 0;\n left: -5px;\n width: 10px;\n}\n.clip-popup .clip-point[data-v-29874490] {\n position: absolute;\n display: block;\n width: 16px;\n height: 16px;\n z-index: 26;\n}\n.clip-popup .point-tr[data-v-29874490] {\n top: -3px;\n right: -3px;\n border-top: 3px solid rgba(50, 135, 255, 1.0);\n border-right: 3px solid rgba(50, 135, 255, 1.0);\n}\n.clip-popup .point-br[data-v-29874490] {\n bottom: -3px;\n right: -3px;\n border-right: 3px solid rgba(50, 135, 255, 1.0);\n border-bottom: 3px solid rgba(50, 135, 255, 1.0);\n}\n.clip-popup .point-tl[data-v-29874490] {\n top: -3px;\n left: -3px;\n border-top: 3px solid rgba(50, 135, 255, 1.0);\n border-left: 3px solid rgba(50, 135, 255, 1.0);\n}\n.clip-popup .point-bl[data-v-29874490] {\n bottom: -3px;\n left: -3px;\n border-bottom: 3px solid rgba(50, 135, 255, 1.0);\n border-left: 3px solid rgba(50, 135, 255, 1.0);\n}\n.clip-popup .range[data-v-29874490] {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n -webkit-justify-content: center;\n justify-content: center;\n position: absolute;\n bottom: 48px;\n left: 0;\n z-index: 30;\n width: 100%;\n height: 30px;\n padding: 0 50px;\n}\n.clip-popup .range input[type=\"range\"][data-v-29874490] {\n -webkit-box-flex: 1;\n -webkit-flex: 1;\n flex: 1;\n display: block;\n margin: 0 20px;\n height: 3px;\n border-radius: 2px;\n background: rgba(255, 255, 255, .8);\n -webkit-appearance: none;\n}\n.clip-popup .range input[type=range][data-v-29874490]::-webkit-slider-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n border: none;\n box-shadow: 0px 0px 3px rgba(255, 255, 255, 1.0);\n background: rgba(50, 135, 255, 1.0);\n -webkit-appearance: none;\n}\n.clip-popup .range span[data-v-29874490] {\n color: #fff;\n}\n/* 弹框切换放大渐变 */\n.opacity-enter-active[data-v-29874490],\n.opacity-leave-active[data-v-29874490] {\n -webkit-transition: all .3s;\n transition: all .3s;\n}\n.opacity-enter[data-v-29874490],\n.opacity-leave-to[data-v-29874490] {\n opacity: 0;\n}\n",""])},function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var i=function(t,e){var i=t[1]||"",n=t[3];if(!n)return i;if(e&&"function"==typeof btoa){var o=(s=n,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+" */"),a=n.sources.map(function(t){return"/*# sourceURL="+n.sourceRoot+t+" */"});return[i].concat(a).concat([o]).join("\n")}var s;return[i].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+i+"}":i}).join("")},e.i=function(t,i){"string"==typeof t&&(t=[[null,t,""]]);for(var n={},o=0;o=0&&p.splice(e,1)}function m(t){var e=document.createElement("style");if(void 0===t.attrs.type&&(t.attrs.type="text/css"),void 0===t.attrs.nonce){var n=function(){0;return i.nc}();n&&(t.attrs.nonce=n)}return v(e,t.attrs),f(t,e),e}function v(t,e){Object.keys(e).forEach(function(i){t.setAttribute(i,e[i])})}function b(t,e){var i,n,o,a;if(e.transform&&t.css){if(!(a="function"==typeof e.transform?e.transform(t.css):e.transform.default(t.css)))return function(){};t.css=a}if(e.singleton){var s=l++;i=c||(c=m(e)),n=y.bind(null,i,s,!1),o=y.bind(null,i,s,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(i=function(t){var e=document.createElement("link");return void 0===t.attrs.type&&(t.attrs.type="text/css"),t.attrs.rel="stylesheet",v(e,t.attrs),f(t,e),e}(e),n=function(t,e,i){var n=i.css,o=i.sourceMap,a=void 0===e.convertToAbsoluteUrls&&o;(e.convertToAbsoluteUrls||a)&&(n=h(n));o&&(n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var s=new Blob([n],{type:"text/css"}),r=t.href;t.href=URL.createObjectURL(s),r&&URL.revokeObjectURL(r)}.bind(null,i,e),o=function(){g(i),i.href&&URL.revokeObjectURL(i.href)}):(i=m(e),n=function(t,e){var i=e.css,n=e.media;n&&t.setAttribute("media",n);if(t.styleSheet)t.styleSheet.cssText=i;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(i))}}.bind(null,i),o=function(){g(i)});return n(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;n(t=e)}else o()}}t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(e=e||{}).attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||"boolean"==typeof e.singleton||(e.singleton=s()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var i=d(t,e);return u(i,e),function(t){for(var n=[],o=0;o=8&&(c=n+o)),c)for(d=u.getUint16(c,a),p=0;pthis.screenWidth-this.clipWidth?this.boxSize.x=this.screenWidth-this.clipWidth:this.boxSize.x=o,a<25?this.boxSize.y=25:a>this.screenHeight-this.clipHeight?this.boxSize.y=this.screenHeight-this.clipHeight:this.boxSize.y=a,this.clipBoxStyle()},leaveClip:function(){window.removeEventListener("mousemove",this.moveClip),window.removeEventListener("mouseup",this.leaveClip),window.removeEventListener("touchmove",this.moveClip),window.removeEventListener("touchend",this.leaveClip)},changeClipSize:function(t,e,i,n,o){t.preventDefault(),window.addEventListener("mousemove",this.changeClipNow),window.addEventListener("mouseup",this.changeClipEnd),window.addEventListener("touchmove",this.changeClipNow),window.addEventListener("touchend",this.changeClipEnd);var a=t.touches?t.touches[0]:t;this.canChangeX=e,this.canChangeY=i,this.changeClipTypeX=n,this.changeClipTypeY=o,this.clipMoveX=a.clientX,this.clipMoveY=a.clientY,this.clipOldX=parseInt(this.boxSize.x),this.clipOldY=parseInt(this.boxSize.y),this.clipWidth=parseInt(this.boxSize.w),this.clipHeight=parseInt(this.boxSize.h),this.fixed&&e&&i&&(this.canChangeY=0)},changeClipNow:function(t){var e=t.touches?t.touches[0]:t,i=parseInt(e.clientX-this.clipMoveX),n=parseInt(e.clientY-this.clipMoveY),o=this.screenWidth,a=this.screenHeight;if(this.canChangeX)if(1===this.changeClipTypeX){var s=this.clipWidth-i,r=this.clipOldX+i;s>0?(this.boxSize.x=r>0?r:0,this.boxSize.w=r>0?s:this.clipWidth+this.clipOldX):(this.boxSize.x=this.clipWidth+this.clipOldX,this.boxSize.w=r>o?o-this.boxSize.x:Math.abs(s))}else if(2===this.changeClipTypeX){var c=this.clipWidth+i,l=this.clipOldX-Math.abs(c);c>0?(this.boxSize.x=this.clipOldX,this.boxSize.w=c+this.clipOldX>o?o-this.clipOldX:c):(this.boxSize.x=l>0?l:0,this.boxSize.w=l>0?Math.abs(c):this.clipOldX)}if(this.canChangeY)if(1===this.changeClipTypeY){var p=this.clipOldY+n,h=this.clipHeight-n;h>0?(this.boxSize.y=p>25?p:25,this.boxSize.h=p>25?h:this.clipHeight+this.clipOldY-25):(this.boxSize.y=this.clipHeight+this.clipOldY,this.boxSize.h=p>a?a-this.boxSize.y:Math.abs(h))}else if(2===this.changeClipTypeY){var u=this.clipHeight+n,d=this.clipOldY-Math.abs(u);u>0?(this.boxSize.y=this.clipOldY,this.boxSize.h=this.clipOldY+u>a?a-this.clipOldY:u):(this.boxSize.y=d>25?d:25,this.boxSize.h=d>25?Math.abs(u):this.clipOldY-25)}var f=this.fixedNumber[0]/this.fixedNumber[1];if(this.canChangeX&&this.fixed){var g=this.boxSize.w/f;g+this.clipOldY>a?(this.boxSize.h=a-this.clipOldY,this.boxSize.w=this.boxSize.h*f):this.boxSize.h=g}if(this.canChangeY&&this.fixed){var m=this.boxSize.h*f;m+this.clipOldX>o?(this.boxSize.w=o-this.clipOldX,this.boxSize.h=this.boxSize.w/f):this.boxSize.w=m}this.clipBoxStyle()},changeClipEnd:function(){window.removeEventListener("mousemove",this.changeClipNow),window.removeEventListener("mouseup",this.changeClipEnd),window.removeEventListener("touchmove",this.changeClipNow),window.removeEventListener("touchend",this.changeClipEnd)}}};i(1);var s=function(t,e,i,n,o,a,s,r){var c,l="function"==typeof t?t.options:t;if(e&&(l.render=e,l.staticRenderFns=i,l._compiled=!0),n&&(l.functional=!0),a&&(l._scopeId="data-v-"+a),s?(c=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(s)},l._ssrRegister=c):o&&(c=r?function(){o.call(this,this.$root.$options.shadowRoot)}:o),c)if(l.functional){l._injectStyles=c;var p=l.render;l.render=function(t,e){return c.call(e),p(t,e)}}else{var h=l.beforeCreate;l.beforeCreate=h?[].concat(h,c):[c]}return{exports:t,options:l}}(a,n,[],!1,null,"29874490",null);s.options.__file="src/vue-clip.vue";var r=s.exports;i.d(e,"VueClip",function(){return r});var c=function(t){t.component(r.name,r)};"undefiend"!=typeof window&&window.Vue&&c(window.Vue);e.default={install:c,VueClip:r,vueClip:r}}])}); -------------------------------------------------------------------------------- /docs/example.bundle.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[0],{202:function(n,t,e){var i=e(207);"string"==typeof i&&(i=[[n.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};e(5)(i,o);i.locals&&(n.exports=i.locals)},203:function(n,t,e){var i=e(209);"string"==typeof i&&(i=[[n.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};e(5)(i,o);i.locals&&(n.exports=i.locals)},204:function(n,t,e){var i=e(212);"string"==typeof i&&(i=[[n.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};e(5)(i,o);i.locals&&(n.exports=i.locals)},205:function(n,t,e){var i=e(215);"string"==typeof i&&(i=[[n.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};e(5)(i,o);i.locals&&(n.exports=i.locals)},206:function(n,t,e){"use strict";var i=e(202);e.n(i).a},207:function(n,t,e){(n.exports=e(4)(!1)).push([n.i,"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* 基础样式文件 */\nhtml, body {\n font-family: 'PingFangSC', 'PingFang SC Bold', 'Microsoft Yahei', Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: 1.5;\n color: #141414;\n background: #fff;\n}\nhtml {\n min-height: 100%;\n}\nbody, h1, h2, h3, h4, h5, h6, hr, p, a, span, em, i, b, section, article, sub, sup, strong\nblockquote, dl, dt, dd, ul, ol, li, pre,\nform, fieldset, legend, button, input, select, textarea, label,\nth, td, img, div, header, footer, nav {\n margin: 0;\n padding: 0;\n border: 0;\n font-weight: normal;\n list-style: none;\n font-style: normal;\n font-size: 14px;\n text-decoration: none;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-tap-highlight-color: transparent;\n -webkit-font-smoothing: antialiased;\n}\n.vue-clip-example {\n width: 1020px;\n margin: 0 auto;\n}\n.vue-clip-example h3 {\n margin: 30px 0;\n font-size: 36px;\n line-height: 80px;\n color: rgba(50, 135, 255, .7);\n font-weight: bold;\n text-align: center;\n}\n.vue-clip-example h4,\n.vue-clip-example a {\n font-size: 22px;\n margin-bottom: 30px;\n}\n.vue-clip-example .content {\n overflow: hidden;\n border-bottom: 6px solid #f9f9f9;\n padding-bottom: 30px;\n margin-bottom: 30px;\n}\n.vue-clip-example .fl {\n position: relative;\n float: left;\n width: 420px;\n height: 700px;\n border: 1px solid #eee;\n}\n.vue-clip-example .fl header {\n height: 40px;\n color: #fff;\n font-size: 20px;\n line-height: 40px;\n text-align: center;\n background: #030303;\n}\n.vue-clip-example .fl .main {\n padding: 20px;\n}\n.vue-clip-example .fr {\n float: right;\n width: 560px;\n height: 700px;\n background: #282a36;\n overflow-y: scroll;\n}\niframe {\n width: 100%;\n height: 100%;\n}\n.avatar {\n width: 60px;\n height: 60px;\n}\n",""])},208:function(n,t,e){"use strict";var i=e(203);e.n(i).a},209:function(n,t,e){(n.exports=e(4)(!1)).push([n.i,"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* 基础样式文件 */\nhtml, body {\n font-family: 'PingFangSC', 'PingFang SC Bold', 'Microsoft Yahei', Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: 1.5;\n color: #141414;\n background: #fff;\n}\nhtml {\n min-height: 100%;\n}\nbody, h1, h2, h3, h4, h5, h6, hr, p, a, span, em, i, b, section, article, sub, sup, strong\nblockquote, dl, dt, dd, ul, ol, li, pre,\nform, fieldset, legend, button, input, select, textarea, label,\nth, td, img, div, header, footer, nav {\n margin: 0;\n padding: 0;\n border: 0;\n font-weight: normal;\n list-style: none;\n font-style: normal;\n font-size: 14px;\n text-decoration: none;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-tap-highlight-color: transparent;\n -webkit-font-smoothing: antialiased;\n}\n.upload header {\n height: 40px;\n color: #fff;\n font-size: 20px;\n line-height: 40px;\n text-align: center;\n background: #030303;\n}\n.upload .main {\n padding: 20px;\n}\n.avatar {\n width: 60px;\n height: 60px;\n}\n",""])},210:function(n,t,e){n.exports=e.p+"img/1.aca4e29.jpg"},211:function(n,t,e){"use strict";var i=e(204);e.n(i).a},212:function(n,t,e){(n.exports=e(4)(!1)).push([n.i,"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* 基础样式文件 */\nhtml, body {\n font-family: 'PingFangSC', 'PingFang SC Bold', 'Microsoft Yahei', Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: 1.5;\n color: #141414;\n background: #fff;\n}\nhtml {\n min-height: 100%;\n}\nbody, h1, h2, h3, h4, h5, h6, hr, p, a, span, em, i, b, section, article, sub, sup, strong\nblockquote, dl, dt, dd, ul, ol, li, pre,\nform, fieldset, legend, button, input, select, textarea, label,\nth, td, img, div, header, footer, nav {\n margin: 0;\n padding: 0;\n border: 0;\n font-weight: normal;\n list-style: none;\n font-style: normal;\n font-size: 14px;\n text-decoration: none;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-tap-highlight-color: transparent;\n -webkit-font-smoothing: antialiased;\n}\n.upload header {\n height: 40px;\n color: #fff;\n font-size: 20px;\n line-height: 40px;\n text-align: center;\n background: #030303;\n}\n.upload .main {\n padding: 20px;\n}\n.avatar {\n width: 60px;\n height: 60px;\n}\n",""])},213:function(n,t,e){n.exports=e.p+"img/2.9e7170f.jpg"},214:function(n,t,e){"use strict";var i=e(205);e.n(i).a},215:function(n,t,e){(n.exports=e(4)(!1)).push([n.i,"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* 基础样式文件 */\nhtml, body {\n font-family: 'PingFangSC', 'PingFang SC Bold', 'Microsoft Yahei', Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: 1.5;\n color: #141414;\n background: #fff;\n}\nhtml {\n min-height: 100%;\n}\nbody, h1, h2, h3, h4, h5, h6, hr, p, a, span, em, i, b, section, article, sub, sup, strong\nblockquote, dl, dt, dd, ul, ol, li, pre,\nform, fieldset, legend, button, input, select, textarea, label,\nth, td, img, div, header, footer, nav {\n margin: 0;\n padding: 0;\n border: 0;\n font-weight: normal;\n list-style: none;\n font-style: normal;\n font-size: 14px;\n text-decoration: none;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-tap-highlight-color: transparent;\n -webkit-font-smoothing: antialiased;\n}\n.upload header {\n height: 40px;\n color: #fff;\n font-size: 20px;\n line-height: 40px;\n text-align: center;\n background: #030303;\n}\n.upload .main {\n padding: 20px;\n}\n.avatar {\n width: 60px;\n height: 60px;\n}\n",""])},216:function(n,t,e){"use strict";e.r(t);var i=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",{staticClass:"upload"},[e("header",[n._v("上传图片")]),n._v(" "),e("div",{staticClass:"main"},[e("div",{staticClass:"avatar"},[e("vue-clip",{attrs:{img:n.option.img,dataUrlType:n.option.dataUrlType,outputSize:n.option.outputSize,isOriginalImg:n.option.isOriginalImg,maxWidth:n.option.maxWidth,maxHeight:n.option.maxHeight,outputType:n.option.outputType,theme:n.option.theme},on:{finish:n.finish}})],1)])])};i._withStripped=!0;var o={name:"upload2",data:function(){return{option:{img:e(210),outputSize:.8,dataUrlType:"base64",isOriginalImg:!1,maxWidth:600,maxHeight:600,outputType:"jpeg",theme:"circle"}}},methods:{finish:function(n,t){console.log("data",t);new FormData}}},a=(e(211),e(1)),r=Object(a.a)(o,i,[],!1,null,null,null);r.options.__file="example/upload2.vue";t.default=r.exports},217:function(n,t,e){"use strict";e.r(t);var i=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",{staticClass:"vue-clip-example"},[e("h3",[n._v("vue-pic-clip")]),n._v(" "),n._m(0),n._v(" "),e("div",{staticClass:"content"},[n._m(1),n._v(" "),e("div",{staticClass:"fr"},[e("div",{directives:[{name:"highlight",rawName:"v-highlight"}]},[e("pre",[n._v(" "),e("code",{domProps:{textContent:n._s(n.code0)}}),n._v("\n ")]),n._v(" "),e("pre",[n._v(" "),e("code",{domProps:{textContent:n._s(n.code1)}}),n._v("\n ")])])])]),n._v(" "),e("div",{staticClass:"content"},[n._m(2),n._v(" "),e("div",{staticClass:"fr"},[e("div",{directives:[{name:"highlight",rawName:"v-highlight"}]},[e("pre",[n._v(" "),e("code",{domProps:{textContent:n._s(n.code4)}}),n._v("\n ")]),n._v(" "),e("pre",[n._v(" "),e("code",{domProps:{textContent:n._s(n.code5)}}),n._v("\n ")])])])]),n._v(" "),e("div",{staticClass:"content"},[n._m(3),n._v(" "),e("div",{staticClass:"fr"},[e("div",{directives:[{name:"highlight",rawName:"v-highlight"}]},[e("pre",[n._v(" "),e("code",{domProps:{textContent:n._s(n.code2)}}),n._v("\n ")]),n._v(" "),e("pre",[n._v(" "),e("code",{domProps:{textContent:n._s(n.code3)}}),n._v("\n ")])])])])])};i._withStripped=!0;var o={name:"app",data:function(){return{code0:"",code1:"",code2:"",code3:"",code4:"",code5:""}},created:function(){this.code0='\n 上传头像',this.code1="\n data () {\n return {\n option: {\n accept: 'image/png, image/jpeg, image/jpg, image/gif', // 可上传的图片类型\n outputSize: 0.7, // 压缩质量\n autoClip: true, // 是否开启截图框\n autoClipWidth: 300, // 截图框宽度\n autoClipHeight: 300, // 截图框高度\n canMoveBox: true, // 截图框是否可以移动\n fixed: false, // 截图框是否开启固定宽高比\n fixedNumber: [1, 1], // 宽高比 w/h\n theme: 'rect' // 样式风格,默认rect:方形,circle:圆形\n }\n }\n },\n methods: {\n finish (name, url) { // 完成上传图片,返回图片名称、数据\n console.log('data', url)\n let formData = new FormData()\n formData.append('files', url)\n formData.append('name', name)\n }\n }",this.code4='\n 上传头像',this.code5="\n data () {\n return {\n option: {\n img: require('./img/2.jpg'), // 默认图片\n accept: 'image/png, image/jpeg, image/jpg, image/gif', // 可上传的图片类型\n outputSize: 0.7, // 压缩质量\n autoClip: true, // 是否开启截图框\n autoClipWidth: 300, // 截图框宽度\n autoClipHeight: 300, // 截图框高度\n canMoveBox: true, // 截图框是否可以移动\n fixed: true, // 截图框是否开启固定宽高比\n fixedNumber: [1, 1], // 宽高比 w/h\n theme: 'rect' // 样式风格,默认rect:方形,circle:圆形\n }\n }\n },\n methods: {\n finish (name, url) { // 完成上传图片,返回图片名称、数据\n console.log('data', url)\n let formData = new FormData()\n formData.append('files', url)\n formData.append('name', name)\n }\n }",this.code2='\n ',this.code3="\n data () {\n return {\n option1: {\n img: require('./img/1.jpg'), // 默认图片\n accept: 'image/png, image/jpeg, image/jpg, image/gif', // 可上传的图片类型\n outputSize: 0.8,\n dataUrlType: 'base64', // 数据类型,默认blob\n isOriginalImg: true, // 是否上传原图,上传原图maxWidth、maxHeight无效\n maxWidth: 600, // 生成图片的最大宽度\n maxHeight: 600, // 生成图片的最大高度\n outputType: 'jpeg', // 生成图片的格式,默认jpg(jpg需要传入jpeg)【jpeg、png、webp】\n theme: 'circle'\n }\n }\n },\n methods: {\n finish (name, url) {\n console.log('data', url)\n }\n }"}},a=(e(206),e(1)),r=Object(a.a)(o,i,[function(){var n=this.$createElement,t=this._self._c||n;return t("h4",[this._v("github: "),t("a",{attrs:{href:"https://github.com/Tianyazz/vue-pic-clip"}},[this._v("https://github.com/Tianyazz/vue-pic-clip")])])},function(){var n=this.$createElement,t=this._self._c||n;return t("div",{staticClass:"fl"},[t("iframe",{attrs:{src:"./#/upload",frameborder:"0"}})])},function(){var n=this.$createElement,t=this._self._c||n;return t("div",{staticClass:"fl"},[t("iframe",{attrs:{src:"./#/upload3",frameborder:"0"}})])},function(){var n=this.$createElement,t=this._self._c||n;return t("div",{staticClass:"fl"},[t("iframe",{attrs:{src:"./#/upload2",frameborder:"0"}})])}],!1,null,null,null);r.options.__file="example/home.vue";t.default=r.exports},218:function(n,t,e){"use strict";e.r(t);var i=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",{staticClass:"upload"},[e("header",[n._v("上传图片")]),n._v(" "),e("div",{staticClass:"main"},[e("div",{staticClass:"avatar"},[e("vue-clip",{attrs:{img:n.option.img,accept:n.option.accept,autoClip:n.option.autoClip,autoClipWidth:n.option.autoClipWidth,autoClipHeight:n.option.autoClipHeight,fixed:n.option.fixed,fixedNumber:n.option.fixedNumber,outputSize:n.option.outputSize,theme:n.option.theme},on:{finish:n.finish}})],1)])])};i._withStripped=!0;var o={name:"upload3",data:function(){return{option:{img:e(213),accept:"image/png, image/jpeg, image/jpg, image/gif",outputSize:.7,autoClip:!0,autoClipWidth:300,autoClipHeight:300,canMoveBox:!0,fixed:!0,fixedNumber:[1,1],theme:"circle"}}},methods:{finish:function(n,t){console.log("data",t);var e=new FormData;e.append("files",t),e.append("name",n)}}},a=(e(214),e(1)),r=Object(a.a)(o,i,[],!1,null,null,null);r.options.__file="example/upload3.vue";t.default=r.exports},219:function(n,t,e){"use strict";e.r(t);var i=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",{staticClass:"upload"},[e("header",[n._v("上传图片")]),n._v(" "),e("div",{staticClass:"main"},[e("div",{staticClass:"avatar"},[e("vue-clip",{attrs:{accept:n.option.accept,autoClip:n.option.autoClip,autoClipWidth:n.option.autoClipWidth,autoClipHeight:n.option.autoClipHeight,fixed:n.option.fixed,outputSize:n.option.outputSize,theme:n.option.theme},on:{finish:n.finish}},[n._v("上传头像")])],1)])])};i._withStripped=!0;var o={name:"upload1",data:function(){return{option:{accept:"image/png, image/jpeg, image/jpg, image/gif",outputSize:.7,autoClip:!0,autoClipWidth:300,autoClipHeight:300,canMoveBox:!1,fixed:!1,fixedNumber:[1,1],theme:"rect"}}},methods:{finish:function(n,t){console.log("data",t);var e=new FormData;e.append("files",t),e.append("name",n)}}},a=(e(208),e(1)),r=Object(a.a)(o,i,[],!1,null,null,null);r.options.__file="example/upload.vue";t.default=r.exports}}]); -------------------------------------------------------------------------------- /docs/img/1.aca4e29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tianyazz/vue-pic-clip/ddc4eed672bc0c0d87a9cb88ef79191993c5742d/docs/img/1.aca4e29.jpg -------------------------------------------------------------------------------- /docs/img/2.9e7170f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tianyazz/vue-pic-clip/ddc4eed672bc0c0d87a9cb88ef79191993c5742d/docs/img/2.9e7170f.jpg -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue image upload 6 | 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /example/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /example/home.vue: -------------------------------------------------------------------------------- 1 | 55 | 56 | 176 | 177 | 264 | -------------------------------------------------------------------------------- /example/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tianyazz/vue-pic-clip/ddc4eed672bc0c0d87a9cb88ef79191993c5742d/example/img/1.jpg -------------------------------------------------------------------------------- /example/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tianyazz/vue-pic-clip/ddc4eed672bc0c0d87a9cb88ef79191993c5742d/example/img/2.jpg -------------------------------------------------------------------------------- /example/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './app' 3 | import router from './router' 4 | import VueClip from '../src/index' 5 | import hljs from 'highlight.js' 6 | import 'highlight.js/styles/dracula.css' 7 | Vue.directive('highlight', function (el) { 8 | let blocks = el.querySelectorAll('pre code'); 9 | setTimeout(() => { 10 | blocks.forEach((block) => { 11 | hljs.highlightBlock(block) 12 | }) 13 | }, 200) 14 | }) 15 | 16 | Vue.use(VueClip) 17 | 18 | new Vue({ 19 | el: '#app', 20 | router, 21 | components: { App }, 22 | template: '' 23 | }) 24 | -------------------------------------------------------------------------------- /example/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | const Home = r => require.ensure([], () => r(require('../home')), 'example') 4 | const Upload = r => require.ensure([], () => r(require('../upload')), 'example') 5 | const Upload2 = r => require.ensure([], () => r(require('../upload2')), 'example') 6 | const Upload3 = r => require.ensure([], () => r(require('../upload3')), 'example') 7 | 8 | Vue.use(Router) 9 | 10 | export default new Router({ 11 | routes: [ 12 | { 13 | path: '/', 14 | component: Home 15 | }, { 16 | path: '/upload', 17 | component: Upload 18 | }, { 19 | path: '/upload2', 20 | component: Upload2 21 | }, { 22 | path: '/upload3', 23 | component: Upload3 24 | } 25 | ] 26 | }) 27 | -------------------------------------------------------------------------------- /example/upload.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 49 | 50 | 96 | -------------------------------------------------------------------------------- /example/upload2.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 47 | 48 | 94 | -------------------------------------------------------------------------------- /example/upload3.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 52 | 53 | 99 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue image upload 6 | 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-pic-clip", 3 | "version": "0.0.1", 4 | "description": "a simple upload cropped image vue plugin", 5 | "author": "", 6 | "private": false, 7 | "main": "./dist/vue-pic-clip.min.js", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "start": "webpack-dev-server --open --config webpack.config.js --host 172.28.3.132", 11 | "doc": "webpack --config webpack.config.js", 12 | "build": "webpack --config webpack.prod.conf.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git@github.com:Tianyazz/vue-pic-clip.git" 17 | }, 18 | "files": [ 19 | "dist", 20 | "src" 21 | ], 22 | "keywords": [ 23 | "vue", 24 | "vue-clip", 25 | "vue-pic-clip", 26 | "vue-component" 27 | ], 28 | "license": "MIT", 29 | "dependencies": { 30 | "vue-router": "^3.0.2", 31 | "webpack-cli": "^3.2.0" 32 | }, 33 | "devDependencies": { 34 | "@babel/core": "^7.2.2", 35 | "@babel/plugin-transform-runtime": "^7.2.0", 36 | "@babel/preset-env": "^7.2.3", 37 | "babel-loader": "^8.0.5", 38 | "clean-webpack-plugin": "^1.0.0", 39 | "css-loader": "^1.0.1", 40 | "extract-text-webpack-plugin": "^3.0.2", 41 | "file-loader": "^3.0.1", 42 | "highlight.js": "^9.13.1", 43 | "html-webpack-plugin": "^3.2.0", 44 | "style-loader": "^0.23.1", 45 | "url-loader": "^1.1.2", 46 | "vue-loader": "^15.5.0", 47 | "vue-template-compiler": "^2.5.21", 48 | "webpack": "^4.28.3", 49 | "webpack-dev-server": "^3.1.14" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import VueClip from './vue-clip' 2 | 3 | const install = function(Vue) { 4 | Vue.component(VueClip.name, VueClip) 5 | } 6 | 7 | if (typeof window !== 'undefiend' && window.Vue) { 8 | install(window.Vue) 9 | } 10 | export { VueClip } 11 | 12 | export default { 13 | install, 14 | VueClip, 15 | vueClip: VueClip 16 | } 17 | -------------------------------------------------------------------------------- /src/vue-clip.vue: -------------------------------------------------------------------------------- 1 | 86 | 87 | 816 | 817 | 1106 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const HtmlWebpackPlugin = require('html-webpack-plugin') 4 | const CleanWebpackPlugin = require('clean-webpack-plugin') 5 | const VueLoaderPlugin = require('vue-loader/lib/plugin') 6 | 7 | module.exports = { 8 | mode: 'production', 9 | entry: './example/main.js', 10 | performance: { 11 | hints: false 12 | }, 13 | devServer: { 14 | contentBase: './docs' 15 | }, 16 | output: { 17 | filename: '[name].bundle.js', 18 | path: path.resolve(__dirname, 'docs') 19 | }, 20 | resolve: { 21 | extensions: ['.js', '.vue'], 22 | alias: { 23 | 'vue$': 'vue/dist/vue.esm.js' 24 | } 25 | }, 26 | module: { 27 | rules: [ 28 | { 29 | test: /\.m?js$/, 30 | exclude: /(node_modules|bower_components)/, 31 | use: { 32 | loader: 'babel-loader', 33 | options: { 34 | presets: ['@babel/preset-env'], 35 | plugins: ['@babel/plugin-transform-runtime'] 36 | } 37 | } 38 | }, 39 | { 40 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 41 | loader: 'url-loader', 42 | options: { 43 | limit: 10000, 44 | name: path.posix.join('img/[name].[hash:7].[ext]') 45 | } 46 | }, 47 | { 48 | test: /\.css$/, 49 | use: [ 50 | 'style-loader', 51 | 'css-loader' 52 | ] 53 | }, 54 | { 55 | test: /\.vue$/, 56 | loader: 'vue-loader' 57 | } 58 | ] 59 | }, 60 | plugins: [ 61 | new CleanWebpackPlugin(['docs']), 62 | new HtmlWebpackPlugin({ 63 | template: 'index.html', 64 | inject: true, // js插入位置 65 | }), 66 | new VueLoaderPlugin() 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const CleanWebpackPlugin = require('clean-webpack-plugin') 4 | const VueLoaderPlugin = require('vue-loader/lib/plugin') 5 | 6 | module.exports = { 7 | mode: 'production', 8 | entry: './src/index.js', 9 | performance: { 10 | hints: false 11 | }, 12 | output: { 13 | path: path.resolve(__dirname, './dist'), 14 | filename: 'vue-pic-clip.min.js', 15 | library: 'Vue-pic-clip', 16 | libraryTarget: 'umd', 17 | umdNamedDefine: true 18 | }, 19 | resolve: { 20 | extensions: ['.js', '.vue'], 21 | alias: { 22 | 'vue$': 'vue/dist/vue.esm.js' 23 | } 24 | }, 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.m?js$/, 29 | exclude: /(node_modules|bower_components)/, 30 | use: { 31 | loader: 'babel-loader', 32 | options: { 33 | presets: ['@babel/preset-env'], 34 | plugins: ['@babel/plugin-transform-runtime'] 35 | } 36 | } 37 | }, 38 | { 39 | test: /\.css$/, 40 | use: [ 41 | 'style-loader', 42 | 'css-loader' 43 | ] 44 | }, 45 | { 46 | test: /\.vue$/, 47 | loader: 'vue-loader' 48 | } 49 | ] 50 | }, 51 | plugins: [ 52 | new CleanWebpackPlugin(['dist']), 53 | new VueLoaderPlugin() 54 | ] 55 | } 56 | --------------------------------------------------------------------------------