vue-editify 0.0.23 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,316 +1,316 @@
1
- <template>
2
- <div class="editify-image">
3
- <div class="editify-image-header">
4
- <div @click="current = 'upload'" class="editify-image-header-item" :class="{ active: current == 'upload' }" :style="activeStyle('upload')">{{ $editTrans('uploadImage') }}</div>
5
- <div @click="current = 'remote'" class="editify-image-header-item" :class="{ active: current == 'remote' }" :style="activeStyle('remote')">{{ $editTrans('remoteImage') }}</div>
6
- <div class="editify-image-header-slider" :class="current" :style="{ backgroundColor: color || '' }"></div>
7
- </div>
8
- <!-- 网络图片 -->
9
- <div class="editify-image-remote" v-if="current == 'remote'">
10
- <input v-model.trim="remoteUrl" :placeholder="$editTrans('imageUrlPlaceholder')" @blur="handleInputBlur" @focus="handleInputFocus" />
11
- <div class="editify-image-remote-footer" :style="{ color: color }">
12
- <span @click="insertRemoteImage">{{ $editTrans('insert') }}</span>
13
- </div>
14
- </div>
15
- <!-- 上传图片 -->
16
- <div class="editify-image-upload" v-else>
17
- <Icon value="upload"></Icon>
18
- <input :multiple="multiple" accept="image/*" @change="selectFile" type="file" />
19
- </div>
20
- </div>
21
- </template>
22
- <script>
23
- import Dap from 'dap-util'
24
- import Icon from '../base/Icon'
25
- export default {
26
- name: 'InsertImage',
27
- emits: ['change', 'insert'],
28
- props: {
29
- //主题色
30
- color: {
31
- type: String,
32
- default: ''
33
- },
34
- //支持的图片类型数组
35
- accept: {
36
- type: Array,
37
- default: null
38
- },
39
- //是否支持多选
40
- multiple: {
41
- type: Boolean,
42
- default: false
43
- },
44
- //单个文件最大值
45
- maxSize: {
46
- type: Number,
47
- default: null
48
- },
49
- //单个文件最小值
50
- minSize: {
51
- type: Number,
52
- default: null
53
- },
54
- //是否自定义上传图片
55
- customUpload: {
56
- type: Function,
57
- default: null
58
- },
59
- //处理上传图片异常
60
- handleError: {
61
- type: Function,
62
- default: null
63
- }
64
- },
65
- inject: ['$editTrans'],
66
- data() {
67
- return {
68
- current: 'upload', //当前展示的面板,取值remote和upload
69
- remoteUrl: '' //远程图片链接
70
- }
71
- },
72
- computed: {
73
- activeStyle() {
74
- return name => {
75
- if (this.current == name) {
76
- return {
77
- color: this.color
78
- }
79
- }
80
- return {}
81
- }
82
- }
83
- },
84
- components: {
85
- Icon
86
- },
87
- watch: {
88
- //监听current变更触发change事件
89
- current() {
90
- this.$emit('change')
91
- }
92
- },
93
- methods: {
94
- //选择文件
95
- async selectFile(e) {
96
- const inputEle = e.currentTarget
97
- const files = inputEle.files
98
- if (!files.length) {
99
- return
100
- }
101
- let filterFiles = []
102
- for (let i = 0; i < files.length; i++) {
103
- const file = files[i]
104
- const suffix = this.getSuffix(file)
105
- const isMatch = this.accept.some(item => {
106
- return item.toLocaleLowerCase() == suffix.toLocaleLowerCase()
107
- })
108
- //后缀不符合
109
- if (!isMatch) {
110
- //如果自定义了异常处理
111
- if (typeof this.handleError == 'function') {
112
- this.handleError.apply(this, ['suffixError', file])
113
- }
114
- continue
115
- }
116
- //超过最大值
117
- if (this.maxSize && file.size / 1024 > this.maxSize) {
118
- //如果自定义了异常处理
119
- if (typeof this.handleError == 'function') {
120
- this.handleError.apply(this, ['maxSizeError', file])
121
- }
122
- continue
123
- }
124
- //没达到最小值
125
- if (this.minSize && file.size / 1024 < this.minSize) {
126
- //如果自定义了异常处理
127
- if (typeof this.handleError == 'function') {
128
- this.handleError.apply(this, ['minSizeError', file])
129
- }
130
- continue
131
- }
132
- filterFiles.push(file)
133
- }
134
- //有文件可上传
135
- if (filterFiles.length) {
136
- //自定义上传方法
137
- if (typeof this.customUpload == 'function') {
138
- this.customUpload.apply(this, [filterFiles])
139
- }
140
- //默认上传方法
141
- else {
142
- let images = []
143
- for (let i = 0; i < filterFiles.length; i++) {
144
- const url = await Dap.file.dataFileToBase64(filterFiles[i])
145
- images.push(url)
146
- }
147
- images.forEach(url => {
148
- this.$emit('insert', url)
149
- })
150
- }
151
- }
152
- //清空文件选择框
153
- inputEle.value = ''
154
- },
155
- //获取文件后缀
156
- getSuffix(file) {
157
- const index = file.name.lastIndexOf('.')
158
- if (index <= 0) {
159
- return ''
160
- }
161
- return file.name.substring(index + 1)
162
- },
163
- //输入框获取焦点
164
- handleInputFocus(e) {
165
- if (this.color) {
166
- e.currentTarget.style.borderColor = this.color
167
- }
168
- },
169
- //输入框失去焦点
170
- handleInputBlur(e) {
171
- e.currentTarget.style.borderColor = ''
172
- },
173
- //插入网络图片
174
- insertRemoteImage() {
175
- this.$emit('insert', this.remoteUrl)
176
- }
177
- }
178
- }
179
- </script>
180
- <style lang="less" scoped>
181
- .editify-image {
182
- display: block;
183
- width: 280px;
184
- padding: 10px 14px;
185
-
186
- .editify-image-header {
187
- display: flex;
188
- justify-content: flex-start;
189
- align-items: center;
190
- width: 100%;
191
- margin-bottom: 20px;
192
- position: relative;
193
- padding-bottom: 6px;
194
-
195
- .editify-image-header-slider {
196
- position: absolute;
197
- width: 50px;
198
- height: 2px;
199
- border-radius: 2px;
200
- left: 0;
201
- bottom: 0;
202
- transition: left 200ms;
203
-
204
- &.upload {
205
- left: 5px;
206
- }
207
-
208
- &.remote {
209
- left: 85px;
210
- }
211
- }
212
-
213
- .editify-image-header-item {
214
- display: block;
215
- text-align: center;
216
- font-size: @font-size;
217
- color: @font-color;
218
- opacity: 0.8;
219
- transition: all 200ms;
220
- width: 60px;
221
- overflow: hidden;
222
- white-space: nowrap;
223
- text-overflow: ellipsis;
224
-
225
- &:hover {
226
- opacity: 1;
227
- cursor: pointer;
228
- }
229
-
230
- &:first-child {
231
- margin-right: 20px;
232
- }
233
-
234
- &.active {
235
- opacity: 1;
236
- color: @font-color-dark;
237
- }
238
- }
239
- }
240
-
241
- .editify-image-remote {
242
- display: block;
243
- width: 100%;
244
-
245
- input {
246
- appearance: none;
247
- -webkit-appearance: none;
248
- -moz-appearance: none;
249
- display: block;
250
- width: 100%;
251
- margin: 0 0 10px 0;
252
- padding: 4px 2px;
253
- border: none;
254
- font-size: @font-size;
255
- color: @font-color;
256
- border-bottom: 1px solid @border-color;
257
- line-height: 1.5;
258
- transition: border-color 500ms;
259
- background-color: transparent;
260
- outline: none;
261
- box-sizing: border-box;
262
-
263
- &::-webkit-input-placeholder,
264
- &::placeholder {
265
- color: @font-color-disabled;
266
- font-family: inherit;
267
- font-size: inherit;
268
- vertical-align: middle;
269
- }
270
- }
271
-
272
- .editify-image-remote-footer {
273
- display: flex;
274
- justify-content: flex-end;
275
- align-items: center;
276
- width: 100%;
277
- font-size: @font-size;
278
- opacity: 0.8;
279
- transition: all 200ms;
280
-
281
- &:hover {
282
- cursor: pointer;
283
- opacity: 1;
284
- }
285
- }
286
- }
287
-
288
- .editify-image-upload {
289
- display: flex;
290
- justify-content: center;
291
- align-items: center;
292
- width: 100%;
293
- padding: 15px 0;
294
- font-size: 36px;
295
- opacity: 0.8;
296
- transition: all 200ms;
297
- position: relative;
298
-
299
- &:hover {
300
- cursor: pointer;
301
- opacity: 1;
302
- }
303
-
304
- input {
305
- opacity: 0;
306
- position: absolute;
307
- left: 0;
308
- top: 0;
309
- width: 100%;
310
- height: 100%;
311
- z-index: 1;
312
- cursor: pointer;
313
- }
314
- }
315
- }
316
- </style>
1
+ <template>
2
+ <div class="editify-image">
3
+ <div class="editify-image-header">
4
+ <div @click="current = 'upload'" class="editify-image-header-item" :class="{ active: current == 'upload' }" :style="activeStyle('upload')">{{ $editTrans('uploadImage') }}</div>
5
+ <div @click="current = 'remote'" class="editify-image-header-item" :class="{ active: current == 'remote' }" :style="activeStyle('remote')">{{ $editTrans('remoteImage') }}</div>
6
+ <div class="editify-image-header-slider" :class="current" :style="{ backgroundColor: color || '' }"></div>
7
+ </div>
8
+ <!-- 网络图片 -->
9
+ <div class="editify-image-remote" v-if="current == 'remote'">
10
+ <input v-model.trim="remoteUrl" :placeholder="$editTrans('imageUrlPlaceholder')" @blur="handleInputBlur" @focus="handleInputFocus" />
11
+ <div class="editify-image-remote-footer" :style="{ color: color }">
12
+ <span @click="insertRemoteImage">{{ $editTrans('insert') }}</span>
13
+ </div>
14
+ </div>
15
+ <!-- 上传图片 -->
16
+ <div class="editify-image-upload" v-else>
17
+ <Icon value="upload"></Icon>
18
+ <input :multiple="multiple" accept="image/*" @change="selectFile" type="file" />
19
+ </div>
20
+ </div>
21
+ </template>
22
+ <script>
23
+ import Dap from 'dap-util'
24
+ import Icon from '../base/Icon'
25
+ export default {
26
+ name: 'InsertImage',
27
+ emits: ['change', 'insert'],
28
+ props: {
29
+ //主题色
30
+ color: {
31
+ type: String,
32
+ default: ''
33
+ },
34
+ //支持的图片类型数组
35
+ accept: {
36
+ type: Array,
37
+ default: null
38
+ },
39
+ //是否支持多选
40
+ multiple: {
41
+ type: Boolean,
42
+ default: false
43
+ },
44
+ //单个文件最大值
45
+ maxSize: {
46
+ type: Number,
47
+ default: null
48
+ },
49
+ //单个文件最小值
50
+ minSize: {
51
+ type: Number,
52
+ default: null
53
+ },
54
+ //是否自定义上传图片
55
+ customUpload: {
56
+ type: Function,
57
+ default: null
58
+ },
59
+ //处理上传图片异常
60
+ handleError: {
61
+ type: Function,
62
+ default: null
63
+ }
64
+ },
65
+ inject: ['$editTrans'],
66
+ data() {
67
+ return {
68
+ current: 'upload', //当前展示的面板,取值remote和upload
69
+ remoteUrl: '' //远程图片链接
70
+ }
71
+ },
72
+ computed: {
73
+ activeStyle() {
74
+ return name => {
75
+ if (this.current == name) {
76
+ return {
77
+ color: this.color
78
+ }
79
+ }
80
+ return {}
81
+ }
82
+ }
83
+ },
84
+ components: {
85
+ Icon
86
+ },
87
+ watch: {
88
+ //监听current变更触发change事件
89
+ current() {
90
+ this.$emit('change')
91
+ }
92
+ },
93
+ methods: {
94
+ //选择文件
95
+ async selectFile(e) {
96
+ const inputEle = e.currentTarget
97
+ const files = inputEle.files
98
+ if (!files.length) {
99
+ return
100
+ }
101
+ let filterFiles = []
102
+ for (let i = 0; i < files.length; i++) {
103
+ const file = files[i]
104
+ const suffix = this.getSuffix(file)
105
+ const isMatch = this.accept.some(item => {
106
+ return item.toLocaleLowerCase() == suffix.toLocaleLowerCase()
107
+ })
108
+ //后缀不符合
109
+ if (!isMatch) {
110
+ //如果自定义了异常处理
111
+ if (typeof this.handleError == 'function') {
112
+ this.handleError.apply(this, ['suffixError', file])
113
+ }
114
+ continue
115
+ }
116
+ //超过最大值
117
+ if (this.maxSize && file.size / 1024 > this.maxSize) {
118
+ //如果自定义了异常处理
119
+ if (typeof this.handleError == 'function') {
120
+ this.handleError.apply(this, ['maxSizeError', file])
121
+ }
122
+ continue
123
+ }
124
+ //没达到最小值
125
+ if (this.minSize && file.size / 1024 < this.minSize) {
126
+ //如果自定义了异常处理
127
+ if (typeof this.handleError == 'function') {
128
+ this.handleError.apply(this, ['minSizeError', file])
129
+ }
130
+ continue
131
+ }
132
+ filterFiles.push(file)
133
+ }
134
+ //有文件可上传
135
+ if (filterFiles.length) {
136
+ //自定义上传方法
137
+ if (typeof this.customUpload == 'function') {
138
+ this.customUpload.apply(this, [filterFiles])
139
+ }
140
+ //默认上传方法
141
+ else {
142
+ let images = []
143
+ for (let i = 0; i < filterFiles.length; i++) {
144
+ const url = await Dap.file.dataFileToBase64(filterFiles[i])
145
+ images.push(url)
146
+ }
147
+ images.forEach(url => {
148
+ this.$emit('insert', url)
149
+ })
150
+ }
151
+ }
152
+ //清空文件选择框
153
+ inputEle.value = ''
154
+ },
155
+ //获取文件后缀
156
+ getSuffix(file) {
157
+ const index = file.name.lastIndexOf('.')
158
+ if (index <= 0) {
159
+ return ''
160
+ }
161
+ return file.name.substring(index + 1)
162
+ },
163
+ //输入框获取焦点
164
+ handleInputFocus(e) {
165
+ if (this.color) {
166
+ e.currentTarget.style.borderColor = this.color
167
+ }
168
+ },
169
+ //输入框失去焦点
170
+ handleInputBlur(e) {
171
+ e.currentTarget.style.borderColor = ''
172
+ },
173
+ //插入网络图片
174
+ insertRemoteImage() {
175
+ this.$emit('insert', this.remoteUrl)
176
+ }
177
+ }
178
+ }
179
+ </script>
180
+ <style lang="less" scoped>
181
+ .editify-image {
182
+ display: block;
183
+ width: 280px;
184
+ padding: 10px 14px;
185
+
186
+ .editify-image-header {
187
+ display: flex;
188
+ justify-content: flex-start;
189
+ align-items: center;
190
+ width: 100%;
191
+ margin-bottom: 20px;
192
+ position: relative;
193
+ padding-bottom: 6px;
194
+
195
+ .editify-image-header-slider {
196
+ position: absolute;
197
+ width: 50px;
198
+ height: 2px;
199
+ border-radius: 2px;
200
+ left: 0;
201
+ bottom: 0;
202
+ transition: left 200ms;
203
+
204
+ &.upload {
205
+ left: 5px;
206
+ }
207
+
208
+ &.remote {
209
+ left: 85px;
210
+ }
211
+ }
212
+
213
+ .editify-image-header-item {
214
+ display: block;
215
+ text-align: center;
216
+ font-size: @font-size;
217
+ color: @font-color;
218
+ opacity: 0.8;
219
+ transition: all 200ms;
220
+ width: 60px;
221
+ overflow: hidden;
222
+ white-space: nowrap;
223
+ text-overflow: ellipsis;
224
+
225
+ &:hover {
226
+ opacity: 1;
227
+ cursor: pointer;
228
+ }
229
+
230
+ &:first-child {
231
+ margin-right: 20px;
232
+ }
233
+
234
+ &.active {
235
+ opacity: 1;
236
+ color: @font-color-dark;
237
+ }
238
+ }
239
+ }
240
+
241
+ .editify-image-remote {
242
+ display: block;
243
+ width: 100%;
244
+
245
+ input {
246
+ appearance: none;
247
+ -webkit-appearance: none;
248
+ -moz-appearance: none;
249
+ display: block;
250
+ width: 100%;
251
+ margin: 0 0 10px 0;
252
+ padding: 4px 2px;
253
+ border: none;
254
+ font-size: @font-size;
255
+ color: @font-color;
256
+ border-bottom: 1px solid @border-color;
257
+ line-height: 1.5;
258
+ transition: border-color 500ms;
259
+ background-color: transparent;
260
+ outline: none;
261
+ box-sizing: border-box;
262
+
263
+ &::-webkit-input-placeholder,
264
+ &::placeholder {
265
+ color: @font-color-disabled;
266
+ font-family: inherit;
267
+ font-size: inherit;
268
+ vertical-align: middle;
269
+ }
270
+ }
271
+
272
+ .editify-image-remote-footer {
273
+ display: flex;
274
+ justify-content: flex-end;
275
+ align-items: center;
276
+ width: 100%;
277
+ font-size: @font-size;
278
+ opacity: 0.8;
279
+ transition: all 200ms;
280
+
281
+ &:hover {
282
+ cursor: pointer;
283
+ opacity: 1;
284
+ }
285
+ }
286
+ }
287
+
288
+ .editify-image-upload {
289
+ display: flex;
290
+ justify-content: center;
291
+ align-items: center;
292
+ width: 100%;
293
+ padding: 15px 0;
294
+ font-size: 36px;
295
+ opacity: 0.8;
296
+ transition: all 200ms;
297
+ position: relative;
298
+
299
+ &:hover {
300
+ cursor: pointer;
301
+ opacity: 1;
302
+ }
303
+
304
+ input {
305
+ opacity: 0;
306
+ position: absolute;
307
+ left: 0;
308
+ top: 0;
309
+ width: 100%;
310
+ height: 100%;
311
+ z-index: 1;
312
+ cursor: pointer;
313
+ }
314
+ }
315
+ }
316
+ </style>