├── .babelrc ├── .editorconfig ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.vue ├── assets │ └── logo.png ├── index.js ├── main.js └── packages │ ├── exif-js.js │ ├── index.js │ └── seikann-upload.vue └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-3" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | 7 | # Editor directories and files 8 | .idea 9 | *.suo 10 | *.ntvs* 11 | *.njsproj 12 | *.sln 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # upload-vue-m 2 | [![NPM version](https://img.shields.io/npm/v/upload-vue-m.svg)](https://www.npmjs.com/package/upload-vue-m) 3 | > 基于vue的图片上传插件,移动PC皆可 4 | ## Build Setup 5 | 6 | ``` bash 7 | # install dependencies 8 | npm install 9 | 10 | # serve with hot reload at localhost:8080 11 | npm run dev 12 | 13 | # build for production with minification 14 | npm run build 15 | ``` 16 | ## npm 安装 17 | ``` bash 18 | npm install upload-vue-m --save 19 | ``` 20 | ## 例 21 | 在main.js中引入 22 | ```js 23 | import upload from 'upload-vue-m' 24 | Vue.use(upload) 25 | ``` 26 | ##在组件中使用 27 | ``` html 28 | // 设置是否允许上传重复图片 Boolean 37 | 38 | ``` 39 | ## 版本 40 | | 版本 | 备注 | 41 | | ------ | ------ | 42 | | 1.1.0 | 基于vue的上传图片基本功能,只是移动端、pc端 | 43 | | 1.1.3 | 更新:修复手机端拍照上传 图片旋转bug | 44 | 45 | ## 参数 46 | 47 | | 参数 | 类型 | 备注 | 必须 | 默认值 | 48 | | ------ | ------ | ------ | ------ | ------ | 49 | | uploadStyle | Object | 设置上传dom样式 | 否 | {width: '80px',height: '80px','background-color': '#ccc'} | 50 | | closeBtnStyle | Object | 设置关闭按钮样式 | 否 | {} | 51 | | accept | String | 设置上传文件格式 | 否 | 'image/*' | 52 | | maxSize | Number | 设置最大文件限制(M) | 否 | 10 | 53 | | maxLength | Number | 设置可上传的最大数量 | 否 | 5 | 54 | | isRepeat | Boolean | 设置是否允许上传重复图片 | 否 | false | 55 | 56 | 57 | ## 事件 58 | 59 | | 事件 | 类型 | 备注 | 60 | | ------ | ------ | ------ | 61 | | getWarning | event | 获取警告信息 | 62 | | getImages | event | 获取需要上传的图文件流。fileList适用于formdata格式上传 和 showList图片展示 | 63 | 64 | 源码地址:[https://github.com/seikann/upload-vue-m](https://github.com/seikann/upload-vue-m) 65 | 66 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader). 67 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | upload-vue-m 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upload-vue-m", 3 | "description": "基于vue的图片上传插件", 4 | "version": "1.1.5", 5 | "author": "seikann <390811346@qq.com>", 6 | "license": "MIT", 7 | "private": false, 8 | "main": "dist/upload-vue-m.js", 9 | "scripts": { 10 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --host 172.16.4.235", 11 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 12 | }, 13 | "keywords": [ 14 | "vue", 15 | "upload", 16 | "图片上传", 17 | "上传", 18 | "图片压缩", 19 | "多图上传", 20 | "图片旋转", 21 | "ios rotate" 22 | ], 23 | "dependencies": { 24 | "vue": "^2.5.11" 25 | }, 26 | "browserslist": [ 27 | "> 1%", 28 | "last 2 versions", 29 | "not ie <= 8" 30 | ], 31 | "devDependencies": { 32 | "babel-core": "^6.26.0", 33 | "babel-loader": "^7.1.2", 34 | "babel-preset-env": "^1.6.0", 35 | "babel-preset-stage-3": "^6.24.1", 36 | "cross-env": "^5.0.5", 37 | "css-loader": "^0.28.7", 38 | "file-loader": "^1.1.4", 39 | "vue-loader": "^13.0.5", 40 | "vue-template-compiler": "^2.4.4", 41 | "webpack": "^3.6.0", 42 | "webpack-dev-server": "^2.9.1" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 34 | 35 | 63 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seikann/upload-vue-m/e6e11168da188f36a2e94ca47a0e2a686a2e02aa/src/assets/logo.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import SeikannUpload from './packages/seikann-upload' 2 | // ...如果还有的话继续添加 3 | 4 | const components = [ 5 | SeikannUpload 6 | // ...如果还有的话继续添加 7 | ] 8 | 9 | const install = function(Vue, opts = {}) { 10 | components.map(component => { 11 | Vue.component(component.name, component); 12 | }) 13 | } 14 | 15 | /* 支持使用标签的方式引入 */ 16 | if (typeof window !== 'undefined' && window.Vue) { 17 | install(window.Vue); 18 | } 19 | 20 | export default { 21 | install, 22 | SeikannUpload 23 | // ...如果还有的话继续添加 24 | } 25 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | new Vue({ 5 | el: '#app', 6 | render: h => h(App) 7 | }) 8 | -------------------------------------------------------------------------------- /src/packages/exif-js.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Minified by jsDelivr using UglifyJS v3.3.25. 3 | * Original file: /npm/exif-js@2.3.0/exif.js 4 | * 5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files 6 | */ 7 | (function(){var d=!1,l=function(e){return e instanceof l?e:this instanceof l?void(this.EXIFwrapped=e):new l(e)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=l),exports.EXIF=l):this.EXIF=l;var u=l.Tags={36864:"ExifVersion",40960:"FlashpixVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",37121:"ComponentsConfiguration",37122:"CompressedBitsPerPixel",37500:"MakerNote",37510:"UserComment",40964:"RelatedSoundFile",36867:"DateTimeOriginal",36868:"DateTimeDigitized",37520:"SubsecTime",37521:"SubsecTimeOriginal",37522:"SubsecTimeDigitized",33434:"ExposureTime",33437:"FNumber",34850:"ExposureProgram",34852:"SpectralSensitivity",34855:"ISOSpeedRatings",34856:"OECF",37377:"ShutterSpeedValue",37378:"ApertureValue",37379:"BrightnessValue",37380:"ExposureBias",37381:"MaxApertureValue",37382:"SubjectDistance",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37396:"SubjectArea",37386:"FocalLength",41483:"FlashEnergy",41484:"SpatialFrequencyResponse",41486:"FocalPlaneXResolution",41487:"FocalPlaneYResolution",41488:"FocalPlaneResolutionUnit",41492:"SubjectLocation",41493:"ExposureIndex",41495:"SensingMethod",41728:"FileSource",41729:"SceneType",41730:"CFAPattern",41985:"CustomRendered",41986:"ExposureMode",41987:"WhiteBalance",41988:"DigitalZoomRation",41989:"FocalLengthIn35mmFilm",41990:"SceneCaptureType",41991:"GainControl",41992:"Contrast",41993:"Saturation",41994:"Sharpness",41995:"DeviceSettingDescription",41996:"SubjectDistanceRange",40965:"InteroperabilityIFDPointer",42016:"ImageUniqueID"},c=l.TiffTags={256:"ImageWidth",257:"ImageHeight",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer",40965:"InteroperabilityIFDPointer",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",274:"Orientation",277:"SamplesPerPixel",284:"PlanarConfiguration",530:"YCbCrSubSampling",531:"YCbCrPositioning",282:"XResolution",283:"YResolution",296:"ResolutionUnit",273:"StripOffsets",278:"RowsPerStrip",279:"StripByteCounts",513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength",301:"TransferFunction",318:"WhitePoint",319:"PrimaryChromaticities",529:"YCbCrCoefficients",532:"ReferenceBlackWhite",306:"DateTime",270:"ImageDescription",271:"Make",272:"Model",305:"Software",315:"Artist",33432:"Copyright"},f=l.GPSTags={0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude",5:"GPSAltitudeRef",6:"GPSAltitude",7:"GPSTimeStamp",8:"GPSSatellites",9:"GPSStatus",10:"GPSMeasureMode",11:"GPSDOP",12:"GPSSpeedRef",13:"GPSSpeed",14:"GPSTrackRef",15:"GPSTrack",16:"GPSImgDirectionRef",17:"GPSImgDirection",18:"GPSMapDatum",19:"GPSDestLatitudeRef",20:"GPSDestLatitude",21:"GPSDestLongitudeRef",22:"GPSDestLongitude",23:"GPSDestBearingRef",24:"GPSDestBearing",25:"GPSDestDistanceRef",26:"GPSDestDistance",27:"GPSProcessingMethod",28:"GPSAreaInformation",29:"GPSDateStamp",30:"GPSDifferential"},g=l.IFD1Tags={256:"ImageWidth",257:"ImageHeight",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",273:"StripOffsets",274:"Orientation",277:"SamplesPerPixel",278:"RowsPerStrip",279:"StripByteCounts",282:"XResolution",283:"YResolution",284:"PlanarConfiguration",296:"ResolutionUnit",513:"JpegIFOffset",514:"JpegIFByteCount",529:"YCbCrCoefficients",530:"YCbCrSubSampling",531:"YCbCrPositioning",532:"ReferenceBlackWhite"},m=l.StringValues={ExposureProgram:{0:"Not defined",1:"Manual",2:"Normal program",3:"Aperture priority",4:"Shutter priority",5:"Creative program",6:"Action program",7:"Portrait mode",8:"Landscape mode"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{0:"Unknown",1:"Daylight",2:"Fluorescent",3:"Tungsten (incandescent light)",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 - 5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},SensingMethod:{1:"Not defined",2:"One-chip color area sensor",3:"Two-chip color area sensor",4:"Three-chip color area sensor",5:"Color sequential area sensor",7:"Trilinear sensor",8:"Color sequential linear sensor"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},SceneType:{1:"Directly photographed"},CustomRendered:{0:"Normal process",1:"Custom process"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},GainControl:{0:"None",1:"Low gain up",2:"High gain up",3:"Low gain down",4:"High gain down"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},SubjectDistanceRange:{0:"Unknown",1:"Macro",2:"Close view",3:"Distant view"},FileSource:{3:"DSC"},Components:{0:"",1:"Y",2:"Cb",3:"Cr",4:"R",5:"G",6:"B"}};function i(e){return!!e.exifdata}function r(i,o){function t(e){var t=p(e);i.exifdata=t||{};var n=function(e){var t=new DataView(e);d&&console.log("Got file of length "+e.byteLength);if(255!=t.getUint8(0)||216!=t.getUint8(1))return d&&console.log("Not a valid JPEG"),!1;var n=2,r=e.byteLength;for(;n")+8,u=(s=s.substring(s.indexOf("e.byteLength)return{};var u=P(e,t,t+l,g,r);if(u.Compression)switch(u.Compression){case 6:if(u.JpegIFOffset&&u.JpegIFByteCount){var c=t+u.JpegIFOffset,d=u.JpegIFByteCount;u.blob=new Blob([new Uint8Array(e.buffer,c,d)],{type:"image/jpeg"})}break;case 1:console.log("Thumbnail image format is TIFF, which is not implemented.");break;default:console.log("Unknown thumbnail image format '%s'",u.Compression)}else 2==u.PhotometricInterpretation&&console.log("Thumbnail image format is RGB, which is not implemented.");return u}(e,s,l,n),r}function b(e){var t={};if(1==e.nodeType){if(0 Vue.component(SeikannUpload.name, SeikannUpload) 4 | 5 | export default SeikannUpload 6 | -------------------------------------------------------------------------------- /src/packages/seikann-upload.vue: -------------------------------------------------------------------------------- 1 | 14 | 42 | 43 | 209 | 210 | 283 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | const NODE_ENV = process.env.NODE_ENV 4 | 5 | module.exports = { 6 | entry: NODE_ENV == 'development' ? './src/main.js' : './src/index.js', 7 | output: { 8 | path: path.resolve(__dirname, './dist'), 9 | publicPath: '/dist/', 10 | filename: 'upload-vue-m.js', 11 | library: 'seikann-ui', // 指定的就是你使用require时的模块名 12 | libraryTarget: 'umd', // libraryTarget会生成不同umd的代码,可以只是commonjs标准的,也可以是指amd标准的,也可以只是通过script标签引入的 13 | umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.css$/, 19 | use: [ 20 | 'vue-style-loader', 21 | 'css-loader' 22 | ], 23 | }, { 24 | test: /\.vue$/, 25 | loader: 'vue-loader', 26 | options: { 27 | loaders: {} 28 | // other vue-loader options go here 29 | } 30 | }, 31 | { 32 | test: /\.js$/, 33 | loader: 'babel-loader', 34 | exclude: /node_modules/ 35 | }, 36 | { 37 | test: /\.(png|jpg|gif|svg)$/, 38 | loader: 'file-loader', 39 | options: { 40 | name: '[name].[ext]?[hash]' 41 | } 42 | } 43 | ] 44 | }, 45 | resolve: { 46 | alias: { 47 | 'vue$': 'vue/dist/vue.esm.js' 48 | }, 49 | extensions: ['*', '.js', '.vue', '.json'] 50 | }, 51 | devServer: { 52 | historyApiFallback: true, 53 | noInfo: true, 54 | overlay: true 55 | }, 56 | performance: { 57 | hints: false 58 | }, 59 | devtool: '#eval-source-map' 60 | } 61 | 62 | if (process.env.NODE_ENV === 'production') { 63 | module.exports.devtool = '#source-map' 64 | // http://vue-loader.vuejs.org/en/workflow/production.html 65 | module.exports.plugins = (module.exports.plugins || []).concat([ 66 | new webpack.DefinePlugin({ 67 | 'process.env': { 68 | NODE_ENV: '"production"' 69 | } 70 | }), 71 | new webpack.optimize.UglifyJsPlugin({ 72 | sourceMap: false, 73 | compress: { 74 | warnings: false 75 | } 76 | }), 77 | new webpack.LoaderOptionsPlugin({ 78 | minimize: true 79 | }) 80 | ]) 81 | } 82 | --------------------------------------------------------------------------------