├── src ├── main.js └── components │ ├── uploader-item.vue │ └── uploader.vue ├── .gitignore ├── .babelrc ├── package.json ├── webpack.config.js └── README.md /src/main.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./components/uploader.vue') 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | *.swp 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false, 5 | "env": { 6 | "test": { 7 | "plugins": [ "istanbul" ] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/uploader-item.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vux-uploader", 3 | "version": "0.1.9", 4 | "main": "./src/main.js", 5 | "description": "vux-uploader Project, the component to upload images", 6 | "author": "greedying ", 7 | "keywords": [ 8 | "vux-uploader", 9 | "vux", 10 | "vue", 11 | "vue ui", 12 | "weui", 13 | "vue-components", 14 | "mobile ui", 15 | "frontend" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/greedying/vux-uploader" 20 | }, 21 | "license": "MIT", 22 | "scripts": { 23 | "dev": "cross-env NODE_ENV=development webpack-dev-server --hot", 24 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 25 | }, 26 | "dependencies": { 27 | "vue": "^2.2.1", 28 | "vux": "^2.1.1-rc.6" 29 | }, 30 | "devDependencies": { 31 | "axios": "^0.15.3", 32 | "babel-core": "^6.22.1", 33 | "babel-eslint": "^7.1.1", 34 | "babel-loader": "^6.2.10", 35 | "babel-plugin-transform-runtime": "^6.22.0", 36 | "babel-preset-es2015": "^6.22.0", 37 | "babel-preset-stage-2": "^6.22.0", 38 | "babel-register": "^6.22.0", 39 | "babel-runtime": "^6.20.0", 40 | "cross-env": "^3.0.0", 41 | "css-loader": "^0.25.0", 42 | "file-loader": "^0.9.0", 43 | "less": "^2.7.1", 44 | "less-loader": "^2.2.3", 45 | "vue-loader": "^10.0.0", 46 | "vue-template-compiler": "^2.2.1", 47 | "webpack": "^2.2.0", 48 | "webpack-dev-server": "^2.2.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/main.js', 6 | output: { 7 | path: path.resolve(__dirname, './dist'), 8 | publicPath: '/dist/', 9 | filename: 'build.js' 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.vue$/, 15 | loader: 'vue-loader', 16 | options: { 17 | loaders: { 18 | } 19 | // other vue-loader options go here 20 | } 21 | }, 22 | { 23 | test: /\.js$/, 24 | loader: 'babel-loader', 25 | exclude: /node_modules/ 26 | } 27 | ] 28 | }, 29 | resolve: { 30 | alias: { 31 | 'vue$': 'vue/dist/vue.common.js' 32 | } 33 | }, 34 | devServer: { 35 | historyApiFallback: true, 36 | noInfo: true 37 | }, 38 | performance: { 39 | hints: false 40 | }, 41 | devtool: '#eval-source-map' 42 | } 43 | 44 | if (process.env.NODE_ENV === 'production') { 45 | module.exports.devtool = '#source-map' 46 | // http://vue-loader.vuejs.org/en/workflow/production.html 47 | module.exports.plugins = (module.exports.plugins || []).concat([ 48 | new webpack.DefinePlugin({ 49 | 'process.env': { 50 | NODE_ENV: '"production"' 51 | } 52 | }), 53 | new webpack.optimize.UglifyJsPlugin({ 54 | sourceMap: true, 55 | compress: { 56 | warnings: false 57 | } 58 | }), 59 | new webpack.LoaderOptionsPlugin({ 60 | minimize: true 61 | }) 62 | ]) 63 | } 64 | -------------------------------------------------------------------------------- /src/components/uploader.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ title }} 7 | 8 | {{ images.length }} / {{ max }} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 159 | 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vux-uploader 2 | 3 | ## vux-uploader是什么 4 | 5 | vux-uploader是一个vue的上传组件,是对[vux](https://github.com/airyland/vux)组件库的一个补充。 6 | 因为vux并没有对[weui](https://github.com/weui/weui)的[uploader组件](https://weui.io/#uploader)进行封装,理由见[vux issue 682](https://github.com/airyland/vux/issues/682),但这又是一个常见需求。在使用vux过程中,作者实现了这个组件,现整理开源出来,命名为vux-uploader。 7 | 8 | ## vux-uploader的特点 9 | 10 | + 基于vux,适合vux项目 11 | + 暂时不支持vux `$t`方式的多语言功能 12 | + 增加了删除按钮,点击则删除第一张图片 13 | + 内置图片上传、增加、删除功能,但暂时每次只能操作一张图片 14 | + 接上,允许用户监听事件,自己实现上传、增加、删除功能 15 | + 使用[axios](https://github.com/mzabriskie/axios)进行图片上传 16 | 17 | 18 | ## 快速使用 19 | 20 | 1. 检查项目是否符合使用条件 21 | * 需要是使用`vux2`的项目 22 | * 需要安装`babel`对`ES6`部分语法进行转码 23 | * 需要安装`less-loader`正确编译less源码 24 | * 只支持`webpack`的方式,暂不提供`umd`版 25 | 26 | 2. 安装`vux-uploader` 27 | ```javascript 28 | npm install vux-uploader --save 29 | ``` 30 | 3. 使用`vux-uploader` 31 | ```javascript 32 | // 引入组件 33 | import Uploader from 'vux-uploader' 34 | ``` 35 | ```javascript 36 | // 子组件 37 | export default { 38 | ... 39 | components: { 40 | ... 41 | Uploader, 42 | ... 43 | } 44 | ... 45 | } 46 | ``` 47 | 48 | ```javascript 49 | // 使用组件 50 | 64 | ``` 65 | 66 | ### props说明 67 | 68 | * images 69 | * `类型`: Array 70 | * `默认值`: [],空数组 71 | * `含义`: 图片数组,格式为 `[ { url: '/url/of/img.ong' }, ...]` 72 | * `备注`: 变量为数组时,数据流为双向,在组件内部改变数组的值影响父组件 73 | 74 | * max 75 | * `类型`: Number 76 | * `默认值`: 1 77 | * `含义`: 图片最大张数 78 | * `备注`: 图片达到max值时,新增按钮消失 79 | 80 | * showHeader 81 | * `类型`: Boolean 82 | * `默认值`: true 83 | * `含义`: 是否显示头部 84 | * `备注`: 控制整个头部的显示 85 | 86 | * title 87 | * `类型`: String 88 | * `默认值`: 图片上传 89 | * `含义`: 头部的标题 90 | * `备注`: 不显示则留空 91 | 92 | * showTip 93 | * `类型`: Boolean 94 | * `默认值`: true 95 | * `含义`: 是否显示头部数字部分,即`1/3`部分 96 | * `备注`: 当`showHeader`为`false`时,header整体隐藏,此时本参数无效 97 | 98 | * readonly 99 | * `类型`: Boolean 100 | * `默认值`: false 101 | * `含义`: 是否只读 102 | * `备注`: 只读时,新增和删除按钮隐藏 103 | 104 | * handleClick 105 | * `类型`: Boolean 106 | * `默认值`: false 107 | * `含义`: 是否接管新增按钮的点击事件,如果是,点击新增按钮不再自动出现选择图片界面 108 | * `备注`: `true`时,点击新增按钮,则`$emit('add-image')`,可以在此事件内进行自定义的选择图片等操作,`此后图片的新增、上传、删除都由使用者接管` 109 | 110 | * autoUpload 111 | * `类型`: Boolean 112 | * `默认值`: true 113 | * `含义`: 选择图片后是否自动上传。是,则调用内部上传接口。否,则`$emit('upload-image', formData)', `formData`为图片内容,用户可监听事件自己上传 114 | * `备注`: handleClick为`true`时,无法进行图片选择,故此参数无效。此参数为`false`时,选择图片后,`$emit('upload-image', formData)', `formData`为图片内容 115 | 116 | * uploadUrl 117 | * `类型`: String 118 | * `默认值`: '' 119 | * `含义`: 接收上传图片的url 120 | * `备注`: 需要返回如下格式的json字符串,否则请设置`autoUpload`为`false`自行上传 121 | 122 | ```javascript 123 | { 124 | result: 0, 125 | message: "result不是0时候的错误信息", 126 | data: { 127 | url: "http://image.url.com/image.png" 128 | } 129 | } 130 | ``` 131 | * name 132 | * `类型`: String 133 | * `默认值`: `img` 134 | * `含义`: 默认上传的时候,图片使用的表单name 135 | * `备注`: 无 136 | 137 | * params 138 | * `类型`: Object 139 | * `默认值`: null 140 | * `含义`: 上传文件时携带参数 141 | * `备注`: 无 142 | 143 | * size 144 | * `类型`: String 145 | * `默认值`: normal 146 | * `含义`: 尺寸类型 147 | * `备注`: `normal`为`weui`默认尺寸,`small`为作者定义的小一些的尺寸 148 | 149 | * capture 150 | * `类型`: String 151 | * `默认值`: '' 152 | * `含义`: input 的capture属性 153 | * `备注`: 可以设置为`camera`,此时点击新增按钮,部分机型会直接调起相机,注意,各型号手机表现不同,请谨慎使用。`handleClick`为true时,此属性无效 154 | 155 | ### emit事件说明 156 | 157 | * add-image 158 | * `emit时机`: 当`handleClick`参数为`true`时,点击新增按钮 159 | * `参数`: 无 160 | * `备注`: 无 161 | 162 | * remove-image 163 | * `emit时机`: 当`handleClick`参数为`true`时,点击删除按钮 164 | * `参数`: 无 165 | * `备注`: 当`handleClick`为`false`时,点击删除按钮,组件内部删除第一张图片;否则,用户需要监听本事件,并进行相应删除操作 166 | 167 | * preview 168 | * `emit时机`: 点击任意一张图片的时候 169 | * `参数`: 图片对象,格式为 `{ url: 'imgUrl' }` 170 | * `备注`: 暂时没有实现自动预览功能,如果需要用户监听事件自行实现 171 | 172 | * upload-image 173 | * `emit时机`: `handleClick和`autoUpload`都为`false`时,选择图片 174 | * `参数`: formData,图片内容生成的formData 175 | * `备注`: 可以通过`vm.$refs.input`获取图片的input元素 176 | 177 | 178 | ## 待实现事项,欢迎PR 179 | 180 | - [ ] 上传进度实时显示 181 | - [ ] 上传错误时,图片显示错误样式 182 | - [ ] 一次选择,多图片上传 183 | - [ ] 其他未实现事项 184 | - [ ] formData 中 'img' 可以配置 185 | - [x] 上传图片时,附带post参数[+16](https://github.com/greedying/vux-uploader/pull/16) 186 | 187 | ## 感谢与参考 188 | 189 | + [vux](https://github.com/airyland/vux) 190 | + [weui](https://github.com/weui/weui) 191 | + [axios](https://github.com/mzabriskie/axios) 192 | + [webpack-simple template](https://github.com/vuejs-templates/webpack-simple) 193 | 194 | ## 疑问与讨论 195 | 196 | + 请先到[issue](https://github.com/greedying/vux-uploader/issues)进行搜索 197 | + 如果上面没有答案,欢迎提[issue](https://github.com/greedying/vux-uploader/issues/new) 198 | + 欢迎加qq群交流,[点此加入](//shang.qq.com/wpa/qunwpa?idkey=b23dade3b260202233283989212dca63bcbb3af8621e850e021cdcb9726d95e2") 199 | --------------------------------------------------------------------------------
{{ title }}