1 | <template>
|
2 | <div class="ro-uploader-wrap" :class="containerClass" :style="containerStyle">
|
3 | <div
|
4 | v-for="(image, index) in images"
|
5 | class="ro-uploader-image-wrap"
|
6 | :class="imageWrapClass"
|
7 | :style="imageWrapStyle">
|
8 | <div v-if="!lazyload"
|
9 | class="ro-uploader-image"
|
10 | :class="imageClass"
|
11 | :style="[{'background-image': 'url(' + image + ')'}, imageStyle]"
|
12 | @click="onClickImage(index)"
|
13 | v-pressure-press="onPress(index)">
|
14 | </div>
|
15 | <div v-else
|
16 | class="ro-uploader-image"
|
17 | :class="imageClass"
|
18 | v-lazy:background-image="image"
|
19 | :style="[imageStyle]"
|
20 | @click="onClickImage(index)"
|
21 | v-pressure-press="onPress(index)">
|
22 | </div>
|
23 | <div v-if="canModify" class="ro-uploader-remove" :class="removeClass" :style="removeStyle" @click="onClickRemove(index)"></div>
|
24 | </div>
|
25 | <div
|
26 | class="ro-uploader-image-wrap ro-uploader-request"
|
27 | v-if="images.length < size && canModify"
|
28 | @click="onClickRequest"
|
29 | :class="requestClass"
|
30 | :style="requestStyle">
|
31 | </div>
|
32 | </div>
|
33 | </template>
|
34 |
|
35 | <script>
|
36 | /**
|
37 | * @load 当图片上传开始时
|
38 | * @finish 当图片上传结束时
|
39 | */
|
40 | export default {
|
41 | name: 'ROUploader',
|
42 | props: {
|
43 | /**
|
44 | * 允许上传图片个数
|
45 | */
|
46 | size: {
|
47 | type: Number,
|
48 | default: 1,
|
49 | },
|
50 | /**
|
51 | * 是否允许修改
|
52 | */
|
53 | canModify: {
|
54 | type: Boolean,
|
55 | default: true,
|
56 | },
|
57 | /**
|
58 | * 容器对象类
|
59 | */
|
60 | containerClass: {
|
61 | type: [ Object, Array, ],
|
62 | default() {
|
63 | return {};
|
64 | },
|
65 | },
|
66 | /**
|
67 | * 容器对象样式
|
68 | */
|
69 | containerStyle: {
|
70 | type: Object,
|
71 | default() {
|
72 | return {};
|
73 | },
|
74 | },
|
75 | /**
|
76 | * 图片对象类
|
77 | */
|
78 | imageClass: {
|
79 | type: [ Object, Array, ],
|
80 | default() {
|
81 | return {};
|
82 | },
|
83 | },
|
84 | /**
|
85 | * 图片对象样式
|
86 | */
|
87 | imageStyle: {
|
88 | type: Object,
|
89 | default() {
|
90 | return {};
|
91 | },
|
92 | },
|
93 | /**
|
94 | * wrap
|
95 | */
|
96 | imageWrapClass: {
|
97 | type: [ Object, Array, ],
|
98 | default() {
|
99 | return {};
|
100 | },
|
101 | },
|
102 | /**
|
103 | * wrap
|
104 | */
|
105 | imageWrapStyle: {
|
106 | type: Object,
|
107 | default() {
|
108 | return {};
|
109 | },
|
110 | },
|
111 | /**
|
112 | * 请求对象类
|
113 | */
|
114 | requestClass: {
|
115 | type: [ Object, Array, ],
|
116 | default() {
|
117 | return {};
|
118 | },
|
119 | },
|
120 | /**
|
121 | * 请求对象样式
|
122 | */
|
123 | requestStyle: {
|
124 | type: Object,
|
125 | default() {
|
126 | return {};
|
127 | },
|
128 | },
|
129 | /**
|
130 | * 删除按钮样式类
|
131 | */
|
132 | removeClass: {
|
133 | type: [ Object, Array, ],
|
134 | default() {
|
135 | return {};
|
136 | },
|
137 | },
|
138 | /**
|
139 | * 删除按钮样式
|
140 | */
|
141 | removeStyle: {
|
142 | type: Object,
|
143 | default() {
|
144 | return {};
|
145 | },
|
146 | },
|
147 | /**
|
148 | * 调用lazyload,因为无法确定存在vue-lazyload库,所以默认false
|
149 | */
|
150 | lazyload: {
|
151 | type: Boolean,
|
152 | default: false,
|
153 | },
|
154 | },
|
155 | data() {
|
156 | return {
|
157 |
|
158 | images: [],
|
159 | };
|
160 | },
|
161 | methods: {
|
162 | /**
|
163 | * 重置所有的images列表,不会触发任何的remove和add事件
|
164 | */
|
165 | setImages(images) {
|
166 | const tmp = [];
|
167 | for (let i = 0, len = images.length; i < len; i++) {
|
168 | tmp.push(images[i]);
|
169 | }
|
170 | this.images = tmp;
|
171 | },
|
172 | /**
|
173 | * 添加图片
|
174 | * 将触发@add(image)事件
|
175 | *
|
176 | * @param {string} image
|
177 | *
|
178 | * @return {boolean} 成功返回true,否则返回false
|
179 | */
|
180 | add(image) {
|
181 | if (this.images.length < this.size) {
|
182 | this.images.push(image);
|
183 | this.$emit('add', image);
|
184 | return true;
|
185 | }
|
186 | return false;
|
187 | },
|
188 | /**
|
189 | * 删除图片
|
190 | * 将触发@remove(index)事件
|
191 | *
|
192 | * @param {number} index
|
193 | *
|
194 | * @return {boolean} true表示删除成功,false表示失败
|
195 | */
|
196 | remove(index) {
|
197 | if (0 <= index && index < this.size) {
|
198 | this.images.splice(index, 1);
|
199 | this.$emit('remove', index);
|
200 | return true;
|
201 | }
|
202 | return false;
|
203 | },
|
204 | /**
|
205 | * 删除所有的图片
|
206 | */
|
207 | removeAll() {
|
208 | for (let i = 0, len = this.images.length; i < len; i++) {
|
209 | this.remove(i);
|
210 | }
|
211 | return true;
|
212 | },
|
213 | /**
|
214 | * 获得所有图片
|
215 | *
|
216 | * @return {Array<string>}
|
217 | */
|
218 | getImages() {
|
219 | return this.images.slice(0);
|
220 | },
|
221 | /**
|
222 | * 当点击图片时触发
|
223 | *
|
224 | * @param {number} index
|
225 | */
|
226 | onClickImage(index) {
|
227 | this.$emit('click', index);
|
228 | },
|
229 | /**
|
230 | * 当点击删除按钮时触发
|
231 | */
|
232 | onClickRemove(index) {
|
233 | this.remove(index);
|
234 | },
|
235 | /**
|
236 | * 当点击添加按钮时
|
237 | */
|
238 | onClickRequest() {
|
239 | this.$emit('request');
|
240 | },
|
241 | /**
|
242 | * 当点击
|
243 | */
|
244 | onPress(index) {
|
245 | return () => {
|
246 | this.$emit('menu', index);
|
247 | }
|
248 | },
|
249 | /**
|
250 | * 获得允许上传的容量
|
251 | */
|
252 | getSize() {
|
253 | return this.size;
|
254 | },
|
255 | /**
|
256 | * 获得当前已经上传的图片的数量
|
257 | */
|
258 | getCount() {
|
259 | return this.images.length;
|
260 | },
|
261 | },
|
262 | };
|
263 | </script>
|
264 |
|
265 | <style lang="less">
|
266 |
|
267 | @color-white: #ffffff;
|
268 |
|
269 | @border-color: #bbbbbb;
|
270 | @active-border-color: darken(@border-color, 20%);
|
271 | @size: 70px;
|
272 | @border-width: 1px;
|
273 |
|
274 | @remove-button-size: 18px;
|
275 |
|
276 | .ro-uploader-wrap {
|
277 | display: flex;
|
278 | background-color: #ffffff;
|
279 | text-decoration: none;
|
280 | .ro-uploader-image-wrap {
|
281 | position: relative;
|
282 | margin-right: 5px;
|
283 | .ro-uploader-image {
|
284 | vertical-align: middle;
|
285 | width: @size;
|
286 | height: @size;
|
287 | background-repeat: no-repeat;
|
288 | background-size: cover;
|
289 | background-position: center;
|
290 | background-color: #aaaaaa;
|
291 | }
|
292 | .ro-uploader-remove {
|
293 | position: absolute;
|
294 | width: @remove-button-size;
|
295 | height: @remove-button-size;
|
296 | font-size: @remove-button-size;
|
297 | line-height: @remove-button-size;
|
298 | color: #ffffff;
|
299 | background-color: #aaaaaa;
|
300 | top: 0rem;
|
301 | right: 0rem;
|
302 | &:before,
|
303 | &:after {
|
304 | background-color: @color-white;
|
305 | transform: translate(-50%, -50%) rotateZ(45deg);
|
306 | }
|
307 | &:before {
|
308 | width: @border-width + 1;
|
309 | height: @remove-button-size;
|
310 | }
|
311 | &:after {
|
312 | width: @remove-button-size;
|
313 | height: @border-width + 1;
|
314 | }
|
315 | &:active {
|
316 | border-color: @color-white;
|
317 | &:before,
|
318 | &:after {
|
319 | background-color: @color-white;
|
320 | }
|
321 | }
|
322 | }
|
323 | }
|
324 | .ro-uploader-request {
|
325 | position: relative;
|
326 | width: @size;
|
327 | height: @size;
|
328 | border: @border-width solid #aaaaaa;
|
329 | box-sizing: border-box;
|
330 | &:before,
|
331 | &:after {
|
332 | background-color: @border-color;
|
333 | }
|
334 | &:before {
|
335 | width: @border-width + 1;
|
336 | height: @size / 2;
|
337 | }
|
338 | &:after {
|
339 | width: @size / 2;
|
340 | height: @border-width + 1;
|
341 | }
|
342 | &:active {
|
343 | border-color: @active-border-color;
|
344 | &:before,
|
345 | &:after {
|
346 | background-color: @active-border-color;
|
347 | }
|
348 | }
|
349 | }
|
350 | .ro-uploader-remove,
|
351 | .ro-uploader-request {
|
352 | &:before,
|
353 | &:after {
|
354 | content: " ";
|
355 | position: absolute;
|
356 | top: 50%;
|
357 | left: 50%;
|
358 | transform: translate(-50%, -50%);
|
359 | }
|
360 | }
|
361 | }
|
362 | </style> |
\ | No newline at end of file |