stellar-ui-v2 1.35.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/common/css/common.scss +61 -0
  2. package/components/ste-animate/README.md +117 -0
  3. package/components/ste-animate/animate.scss +247 -0
  4. package/components/ste-animate/ste-animate.vue +200 -0
  5. package/components/ste-badge/README.md +171 -0
  6. package/components/ste-badge/ste-badge.vue +238 -0
  7. package/components/ste-barcode/README.md +36 -0
  8. package/components/ste-barcode/encode2.js +317 -0
  9. package/components/ste-barcode/ste-barcode.vue +213 -0
  10. package/components/ste-button/README.md +129 -0
  11. package/components/ste-button/ste-button.vue +345 -0
  12. package/components/ste-calendar/README.md +304 -0
  13. package/components/ste-calendar/self-date.js +119 -0
  14. package/components/ste-calendar/ste-calendar.vue +578 -0
  15. package/components/ste-checkbox/README.md +297 -0
  16. package/components/ste-checkbox/ste-checkbox.vue +305 -0
  17. package/components/ste-checkbox-group/ste-checkbox-group.vue +133 -0
  18. package/components/ste-code-input/README.md +67 -0
  19. package/components/ste-code-input/ste-code-input.vue +302 -0
  20. package/components/ste-date-picker/README.md +135 -0
  21. package/components/ste-date-picker/ste-date-picker.vue +407 -0
  22. package/components/ste-drag/README.md +103 -0
  23. package/components/ste-drag/ste-drag.vue +203 -0
  24. package/components/ste-dropdown-menu/README.md +358 -0
  25. package/components/ste-dropdown-menu/ste-dropdown-menu.vue +405 -0
  26. package/components/ste-dropdown-menu-item/ste-dropdown-menu-item.vue +176 -0
  27. package/components/ste-icon/README.md +90 -0
  28. package/components/ste-icon/iconfont.css +8 -0
  29. package/components/ste-icon/ste-icon.vue +147 -0
  30. package/components/ste-image/README.md +154 -0
  31. package/components/ste-image/ste-image.vue +218 -0
  32. package/components/ste-index-item/ste-index-item.vue +96 -0
  33. package/components/ste-index-list/README.md +153 -0
  34. package/components/ste-index-list/ste-index-list.vue +128 -0
  35. package/components/ste-input/README.md +146 -0
  36. package/components/ste-input/ste-input.vue +480 -0
  37. package/components/ste-loading/README.md +81 -0
  38. package/components/ste-loading/ste-loading.vue +166 -0
  39. package/components/ste-media-preview/README.md +243 -0
  40. package/components/ste-media-preview/TouchScaleing.js +102 -0
  41. package/components/ste-media-preview/ste-media-preview.vue +267 -0
  42. package/components/ste-message-box/README.md +217 -0
  43. package/components/ste-message-box/ste-message-box.js +72 -0
  44. package/components/ste-message-box/ste-message-box.vue +380 -0
  45. package/components/ste-notice-bar/README.md +129 -0
  46. package/components/ste-notice-bar/ste-notice-bar.vue +331 -0
  47. package/components/ste-number-keyboard/README.md +246 -0
  48. package/components/ste-number-keyboard/keyboard.vue +140 -0
  49. package/components/ste-number-keyboard/ste-number-keyboard.vue +240 -0
  50. package/components/ste-picker/ste-picker.vue +258 -0
  51. package/components/ste-popup/README.md +148 -0
  52. package/components/ste-popup/ste-popup.vue +337 -0
  53. package/components/ste-price/README.md +129 -0
  54. package/components/ste-price/ste-price.vue +258 -0
  55. package/components/ste-progress/README.md +87 -0
  56. package/components/ste-progress/ste-progress.vue +200 -0
  57. package/components/ste-qrcode/README.md +50 -0
  58. package/components/ste-qrcode/ste-qrcode.vue +164 -0
  59. package/components/ste-qrcode/uqrcode.js +34 -0
  60. package/components/ste-radio/README.md +286 -0
  61. package/components/ste-radio/ste-radio.vue +293 -0
  62. package/components/ste-radio-group/ste-radio-group.vue +128 -0
  63. package/components/ste-rate/README.md +115 -0
  64. package/components/ste-rate/ste-rate.vue +202 -0
  65. package/components/ste-read-more/README.md +111 -0
  66. package/components/ste-read-more/ste-read-more.vue +133 -0
  67. package/components/ste-rich-text/README.md +31 -0
  68. package/components/ste-rich-text/ste-rich-text.vue +70 -0
  69. package/components/ste-scroll-to/README.md +68 -0
  70. package/components/ste-scroll-to/mixin.js +173 -0
  71. package/components/ste-scroll-to/ste-scroll-to.vue +45 -0
  72. package/components/ste-scroll-to-item/ste-scroll-to-item.vue +25 -0
  73. package/components/ste-search/README.md +262 -0
  74. package/components/ste-search/ste-search.vue +547 -0
  75. package/components/ste-select/README.md +434 -0
  76. package/components/ste-select/datapager.vue +62 -0
  77. package/components/ste-select/datetime.vue +106 -0
  78. package/components/ste-select/defaultDate.js +142 -0
  79. package/components/ste-select/ste-select.vue +843 -0
  80. package/components/ste-signature/README.md +105 -0
  81. package/components/ste-signature/ste-signature.vue +220 -0
  82. package/components/ste-slider/README.md +165 -0
  83. package/components/ste-slider/ste-slider.vue +544 -0
  84. package/components/ste-step/ste-step.vue +264 -0
  85. package/components/ste-stepper/README.md +170 -0
  86. package/components/ste-stepper/ste-stepper.vue +373 -0
  87. package/components/ste-steps/README.md +132 -0
  88. package/components/ste-steps/ste-steps.vue +65 -0
  89. package/components/ste-sticky/README.md +52 -0
  90. package/components/ste-sticky/ste-sticky.vue +127 -0
  91. package/components/ste-swipe-action/README.md +197 -0
  92. package/components/ste-swipe-action/ste-swipe-action.vue +303 -0
  93. package/components/ste-swipe-action-group/ste-swipe-action-group.vue +104 -0
  94. package/components/ste-swiper/README.md +173 -0
  95. package/components/ste-swiper/ste-swiper.vue +462 -0
  96. package/components/ste-swiper-item/ste-swiper-item.vue +41 -0
  97. package/components/ste-switch/README.md +110 -0
  98. package/components/ste-switch/ste-switch.vue +144 -0
  99. package/components/ste-tab/ste-tab.vue +87 -0
  100. package/components/ste-table/README.md +785 -0
  101. package/components/ste-table/common.js +8 -0
  102. package/components/ste-table/ste-table.vue +666 -0
  103. package/components/ste-table/utils.js +20 -0
  104. package/components/ste-table-column/checkbox-icon.vue +65 -0
  105. package/components/ste-table-column/common.scss +65 -0
  106. package/components/ste-table-column/radio-icon.vue +110 -0
  107. package/components/ste-table-column/ste-table-column.vue +255 -0
  108. package/components/ste-table-column/sub-table.vue +116 -0
  109. package/components/ste-table-column/table-popover.vue +204 -0
  110. package/components/ste-table-column/var.scss +1 -0
  111. package/components/ste-tabs/README.md +475 -0
  112. package/components/ste-tabs/props.js +212 -0
  113. package/components/ste-tabs/ste-tabs.vue +758 -0
  114. package/components/ste-text/README.md +66 -0
  115. package/components/ste-text/ste-text.vue +72 -0
  116. package/components/ste-toast/README.md +243 -0
  117. package/components/ste-toast/ste-toast.js +69 -0
  118. package/components/ste-toast/ste-toast.vue +231 -0
  119. package/components/ste-touch-swipe/README.md +104 -0
  120. package/components/ste-touch-swipe/TouchEvent.js +72 -0
  121. package/components/ste-touch-swipe/ste-touch-swipe.vue +327 -0
  122. package/components/ste-touch-swipe-item/ste-touch-swipe-item.vue +33 -0
  123. package/components/ste-tour/README.md +194 -0
  124. package/components/ste-tour/ste-tour.vue +355 -0
  125. package/components/ste-tree/README.md +240 -0
  126. package/components/ste-tree/ste-tree.vue +350 -0
  127. package/components/ste-upload/README.md +276 -0
  128. package/components/ste-upload/ReadFile.js +229 -0
  129. package/components/ste-upload/ste-upload.vue +526 -0
  130. package/components/ste-video/README.md +60 -0
  131. package/components/ste-video/props.js +149 -0
  132. package/components/ste-video/ste-video.vue +647 -0
  133. package/config/color.js +22 -0
  134. package/index.js +2 -0
  135. package/package.json +19 -0
  136. package/utils/Color.js +66 -0
  137. package/utils/System.js +110 -0
  138. package/utils/dayjs.min.js +1 -0
  139. package/utils/mixin.js +67 -0
  140. package/utils/store.js +7 -0
  141. package/utils/utils.js +604 -0
@@ -0,0 +1,407 @@
1
+ <template>
2
+ <view class="ste-date-picker-root">
3
+ <ste-picker
4
+ :columns="columns"
5
+ :title="title"
6
+ :showToolbar="showToolbar"
7
+ :cancelText="cancelText"
8
+ :cancelColor="cancelColor"
9
+ :confirmText="confirmText"
10
+ :confirmColor="cmpConfirmColor"
11
+ :visibleItemCount="visibleItemCount"
12
+ :defaultIndex="innerDefaultIndex"
13
+ :itemHeight="itemHeight"
14
+ @change="change"
15
+ @cancel="cancel"
16
+ @confirm="confirm"
17
+ rootClass="ste-date-picker-view"
18
+ ></ste-picker>
19
+ </view>
20
+ </template>
21
+
22
+ <script>
23
+ import utils from '../../utils/utils.js';
24
+ import dayjs from '../../utils/dayjs.min.js';
25
+ import useColor from '../../config/color.js';
26
+ let color = useColor();
27
+ /**
28
+ * ste-date-picker 时间日期选择器
29
+ * @description 此选择器用于时间日期
30
+ * @tutorial https://stellar-ui.intecloud.com.cn/pc/index/index?name=ste-date-picker
31
+ * @property {String | Number} value 绑定值
32
+ * @property {Boolean} showToolbar 是否显示顶部的操作栏 ( 默认 true )
33
+ * @property {String} title 顶部标题
34
+ * @property {String} mode 展示格式 (默认 all)
35
+ * @value all 年月日时分秒 {{String}}
36
+ * @value datetime 年月日时分 {{String}}
37
+ * @value date 年月日 {{String}}
38
+ * @value year-month 年月 {{String}}
39
+ * @value month-day 月日 {{String}}
40
+ * @value time 时分秒 {{String}}
41
+ * @value hour-minute 时分 {{String}}
42
+ * @value minute-second 分秒 {{String}}
43
+ * @property {Number} maxDate 可选的最大时间 默认值为后10年
44
+ * @property {Number} minDate 可选的最小时间 默认值为前10年
45
+ * @property {Function} filter 选项过滤函数
46
+ * @property {Function} formatter 选项格式化函数
47
+ * @property {String | Number} itemHeight 各列中,单个选项的高度 ( 默认 36 )
48
+ * @property {String} cancelText 取消按钮的文字 ( 默认 '取消' )
49
+ * @property {String} confirmText 确认按钮的文字 ( 默认 '确认' )
50
+ * @property {String} cancelColor 取消按钮的颜色 ( 默认 '#909193' )
51
+ * @property {String} confirmColor 确认按钮的颜色 ( 默认 '#3c9cff' )
52
+ * @property {String | Number} visibleItemCount 每列中可见选项的数量 ( 默认 5 )
53
+ * @event {Function} confirm 点击确定按钮,返回当前选择的值
54
+ * @event {Function} change 当选择值变化时触发
55
+ * @event {Function} cancel 点击取消按钮
56
+ */
57
+
58
+ const DEFAULT_DATE = dayjs(new Date(1970, 1, 1, 0, 0, 0));
59
+
60
+ const padZero = (value) => {
61
+ return `00${value}`.slice(-2);
62
+ };
63
+ const times = (n, iteratee) => {
64
+ let index = -1;
65
+ const result = Array(n < 0 ? 0 : n);
66
+ while (++index < n) {
67
+ result[index] = iteratee(index);
68
+ }
69
+ return result;
70
+ };
71
+
72
+ export default {
73
+ group: '表单组件',
74
+ title: 'DatePicker 时间选择器',
75
+ name: 'ste-date-picker',
76
+ props: {
77
+ // 是否展示顶部的操作栏
78
+ showToolbar: {
79
+ type: [Boolean, null],
80
+ default: true,
81
+ },
82
+ // 绑定值
83
+ value: {
84
+ type: [String, Number, null],
85
+ default: '',
86
+ },
87
+ // 顶部标题
88
+ title: {
89
+ type: [String, null],
90
+ default: '',
91
+ },
92
+ /**
93
+ * 年月日时分秒(all),年月日时分(datetime),年月日(date),年月(year-month),月日(month-day),时分秒(time),时分(hour-minute),分秒(minute-second),
94
+ */
95
+ mode: {
96
+ type: [String, null],
97
+ default: 'all',
98
+ },
99
+ // 可选的最大时间
100
+ maxDate: {
101
+ type: [Number, String, null],
102
+ // 最大默认值为后10年
103
+ default: new Date(new Date().getFullYear() + 10, 11, 31, 23, 59, 59).getTime(),
104
+ },
105
+ // 可选的最小时间
106
+ minDate: {
107
+ type: [Number, String, Object, null],
108
+ // 最小默认值为前10年
109
+ default: new Date(new Date().getFullYear() - 10, 0, 1).getTime(),
110
+ },
111
+ // 选项过滤函数
112
+ filter: {
113
+ type: [Function, null],
114
+ default: null,
115
+ },
116
+ // 选项格式化函数
117
+ formatter: {
118
+ type: [Function, null],
119
+ default: null,
120
+ },
121
+ // 各列中,单个选项的高度
122
+ itemHeight: {
123
+ type: [String, Number, null],
124
+ default: 43,
125
+ },
126
+ // 取消按钮的文字
127
+ cancelText: {
128
+ type: [String, null],
129
+ default: '取消',
130
+ },
131
+ // 确认按钮的文字
132
+ confirmText: {
133
+ type: [String, null],
134
+ default: '确认',
135
+ },
136
+ // 取消按钮的颜色
137
+ cancelColor: {
138
+ type: [String, null],
139
+ default: '#969799',
140
+ },
141
+ // 确认按钮的颜色
142
+ confirmColor: {
143
+ type: [String, null],
144
+ default: '',
145
+ },
146
+ // 每列中可见选项的数量
147
+ visibleItemCount: {
148
+ type: [String, Number, null],
149
+ default: 5,
150
+ },
151
+ },
152
+
153
+ data() {
154
+ return {
155
+ columns: [],
156
+ innerValue: '',
157
+ innerDefaultIndex: [],
158
+ innerFormatter: (type, value) => value,
159
+ };
160
+ },
161
+ computed: {
162
+ cmpConfirmColor() {
163
+ return this.confirmColor ? this.confirmColor : color.getColor().steThemeColor;
164
+ },
165
+ },
166
+ created() {
167
+ this.init();
168
+ },
169
+ methods: {
170
+ init() {
171
+ this.innerValue = this.correctValue(this.value);
172
+ this.updateColumnValue(this.innerValue);
173
+ },
174
+ updateColumnValue(value) {
175
+ this.innerValue = value;
176
+ this.updateColumns();
177
+ this.updateIndexs();
178
+ },
179
+ updateColumns() {
180
+ const formatter = this.formatter || this.innerFormatter;
181
+ const result = this.getOriginColumns().map((column) =>
182
+ column.values.map((value) => formatter(column.type, value))
183
+ );
184
+ this.columns = result;
185
+ },
186
+ // 更新索引
187
+ updateIndexs() {
188
+ let value = this.innerValue;
189
+ let values = [];
190
+ const formatter = this.formatter || this.innerFormatter;
191
+ values.push(
192
+ formatter('year', `${dayjs(value).year()}`),
193
+ formatter('month', padZero(dayjs(value).month() + 1)),
194
+ formatter('day', padZero(dayjs(value).date())),
195
+ formatter('hour', padZero(dayjs(value).hour())),
196
+ formatter('minute', padZero(dayjs(value).minute())),
197
+ formatter('second', padZero(dayjs(value).second()))
198
+ );
199
+
200
+ // 不同mode下的时间是连续值,需要计算不同mode下对应完整时间的初始替换下标即可
201
+ let startFlag = 0;
202
+ switch (this.mode) {
203
+ case 'month-day':
204
+ startFlag = 1;
205
+ break;
206
+ case 'time':
207
+ case 'hour-minute':
208
+ startFlag = 3;
209
+ break;
210
+ case 'minute-second':
211
+ startFlag = 4;
212
+ }
213
+
214
+ // 根据当前各列的所有值,从各列默认值中找到默认值在各列中的索引
215
+ const indexs = this.columns.map((column, index) => {
216
+ // 通过取大值,可以保证不会出现找不到索引的-1情况
217
+ return Math.max(
218
+ 0,
219
+ column.findIndex((item) => item === values[index + startFlag])
220
+ );
221
+ });
222
+
223
+ this.innerDefaultIndex = indexs;
224
+ },
225
+ getOriginColumns() {
226
+ // 生成各列的值
227
+ const results = this.getRanges().map(({ type, range }) => {
228
+ let values = times(range[1] - range[0] + 1, (index) => {
229
+ let value = range[0] + index;
230
+ value = type === 'year' ? `${value}` : padZero(value);
231
+ return value;
232
+ });
233
+ // 进行过滤
234
+ if (this.filter) {
235
+ values = this.filter(type, values);
236
+ }
237
+ return { type, values };
238
+ });
239
+ return results;
240
+ },
241
+ // 获取每列的最大和最小值
242
+ getRanges() {
243
+ const { maxYear, maxDate, maxMonth, maxHour, maxMinute, maxSecond } = this.getBoundary(
244
+ 'max',
245
+ this.innerValue
246
+ );
247
+ const { minYear, minDate, minMonth, minHour, minMinute, minSecond } = this.getBoundary(
248
+ 'min',
249
+ this.innerValue
250
+ );
251
+
252
+ const result = [
253
+ {
254
+ type: 'year',
255
+ range: [minYear, maxYear],
256
+ },
257
+ {
258
+ type: 'month',
259
+ range: [minMonth, maxMonth],
260
+ },
261
+ {
262
+ type: 'day',
263
+ range: [minDate, maxDate],
264
+ },
265
+ {
266
+ type: 'hour',
267
+ range: [minHour, maxHour],
268
+ },
269
+ {
270
+ type: 'minute',
271
+ range: [minMinute, maxMinute],
272
+ },
273
+ {
274
+ type: 'second',
275
+ range: [minSecond, maxSecond],
276
+ },
277
+ ];
278
+ let temp = result;
279
+ if (this.mode === 'datetime') temp = result.splice(0, 5);
280
+ if (this.mode === 'date') temp = result.splice(0, 3);
281
+ if (this.mode === 'year-month') temp = result.splice(0, 2);
282
+ if (this.mode === 'month-day') temp = result.splice(1, 2);
283
+ if (this.mode === 'time') temp = result.splice(3, 3);
284
+ if (this.mode === 'hour-minute') temp = result.splice(3, 2);
285
+ if (this.mode === 'minute-second') temp = result.splice(4, 2);
286
+ return temp;
287
+ },
288
+ // 根据minDate、maxDate、minHour、maxHour等边界值,判断各列的开始和结束边界值
289
+ getBoundary(type, innerValue) {
290
+ const value = dayjs(innerValue);
291
+ const boundary = dayjs(this[`${type}Date`]);
292
+ const year = boundary.year();
293
+ let month = 1;
294
+ let date = 1;
295
+ let hour = 0;
296
+ let minute = 0;
297
+
298
+ if (type === 'max') {
299
+ month = 12;
300
+ date = dayjs(value).daysInMonth();
301
+ hour = 23;
302
+ minute = 59;
303
+ }
304
+
305
+ // 获取边界值,逻辑是:当年达到了边界值(最大或最小年),就检查月允许的最大和最小值,以此类推
306
+ let second = minute;
307
+ if (value.year() === year) {
308
+ month = boundary.month() + 1;
309
+ if (value.month() + 1 === month) {
310
+ date = boundary.date();
311
+ if (value.date() === date) {
312
+ hour = boundary.hour();
313
+ if (value.hour() === hour) {
314
+ minute = boundary.minute();
315
+ if (value.minute() === minute) second = boundary.second();
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ return {
322
+ [`${type}Year`]: year,
323
+ [`${type}Month`]: month,
324
+ [`${type}Date`]: date,
325
+ [`${type}Hour`]: hour,
326
+ [`${type}Minute`]: minute,
327
+ [`${type}Second`]: second,
328
+ };
329
+ },
330
+ // 得出合法的时间
331
+ correctValue(value) {
332
+ let date = dayjs(value);
333
+ if (date.isValid()) {
334
+ if (date.isBefore(dayjs(this.minDate))) {
335
+ date = this.minDate;
336
+ } else if (date.isAfter(dayjs(this.maxDate))) {
337
+ date = this.maxDate;
338
+ }
339
+ } else {
340
+ date = dayjs();
341
+ }
342
+
343
+ return date.valueOf();
344
+ },
345
+ change(e) {
346
+ const { indexs, values } = e;
347
+ let selectValue = '';
348
+
349
+ // 取默认时间中的值,然后再通过mode和变化值来替换默认值
350
+ let dateArr = [
351
+ DEFAULT_DATE.year(),
352
+ DEFAULT_DATE.month() + 1,
353
+ DEFAULT_DATE.day(),
354
+ DEFAULT_DATE.hour(),
355
+ DEFAULT_DATE.minute(),
356
+ DEFAULT_DATE.second(),
357
+ ];
358
+ // 不同mode下的时间是连续值,需要计算不同mode下对应完整时间的初始替换下标即可
359
+ let startFlag = 0;
360
+ switch (this.mode) {
361
+ case 'month-day':
362
+ startFlag = 1;
363
+ break;
364
+ case 'time':
365
+ case 'hour-minute':
366
+ startFlag = 3;
367
+ break;
368
+ case 'minute-second':
369
+ startFlag = 4;
370
+ }
371
+ indexs.forEach((e, i) => {
372
+ let v = parseInt(values[i][e]);
373
+ dateArr[startFlag + i] = v;
374
+ });
375
+
376
+ // 此月份的最大天数
377
+ const maxDay = dayjs(`${dateArr[0]}-${dateArr[1]}`).daysInMonth();
378
+ dateArr[2] = Math.min(maxDay, dateArr[2]) || 1;
379
+
380
+ selectValue = Number(new Date(dateArr[0], dateArr[1] - 1, dateArr[2], dateArr[3], dateArr[4], dateArr[5]));
381
+ selectValue = this.correctValue(selectValue);
382
+ this.innerValue = selectValue;
383
+ this.updateColumnValue(selectValue);
384
+
385
+ // 发出change事件,value为当前选中的时间戳
386
+ this.$emit('change', {
387
+ value: selectValue,
388
+ mode: this.mode,
389
+ });
390
+ },
391
+ cancel() {
392
+ this.$emit('cancel');
393
+ },
394
+ confirm() {
395
+ this.$emit('confirm', this.innerValue);
396
+ },
397
+ },
398
+ };
399
+ </script>
400
+
401
+ <style lang="scss" scoped>
402
+ .ste-date-picker-root {
403
+ // /deep/ view {
404
+ // padding: 0 42rpx;
405
+ // }
406
+ }
407
+ </style>
@@ -0,0 +1,103 @@
1
+ # Drag 拖拽
2
+ 用于拖拽的容器
3
+
4
+ ---$
5
+
6
+
7
+ ### 代码演示
8
+ #### 自由拖拽
9
+ ```html
10
+ <ste-drag>
11
+ <ste-button>拖拽按钮</ste-button>
12
+ </ste-drag>
13
+ ```
14
+
15
+ #### 固定方向
16
+ ```html
17
+ <ste-drag direction="x">
18
+ <ste-button>横向固定</ste-button>
19
+ </ste-drag>
20
+
21
+ <ste-drag direction="y">
22
+ <ste-button>竖向固定</ste-button>
23
+ </ste-drag>
24
+ ```
25
+
26
+ #### 贴边
27
+ 会根据元素移动结束时到左右边界距离来进行贴边
28
+ ```html
29
+ <ste-drag attract>
30
+ <ste-button>贴边</ste-button>
31
+ </ste-drag>
32
+ ```
33
+
34
+ #### 边界
35
+ - 数据结构是 `{top: 0, right: 0, bottom: 0, left: 0}`,分别代表距离屏幕上、右、下、左的距离(单位px)
36
+ - 可按照样例中的做法,根据屏幕大小动态边界值
37
+
38
+ ```html
39
+ <template>
40
+ <view style="width: 300px; height: 150px; border: solid 1px red" class="boundary-box">
41
+ <ste-drag :boundary="boundary">
42
+ <ste-button>边界</ste-button>
43
+ </ste-drag>
44
+ </view>
45
+ </template>
46
+ <script>
47
+ import utils from '@/common/utils.js';
48
+ export default {
49
+ data() {
50
+ return {
51
+ boundary: null,
52
+ }
53
+ },
54
+ mounted() {
55
+ const boundary = { left: 22, top: 354 };
56
+ const systemInfo = utils.getWindowInfo();
57
+ boundary.right = systemInfo.windowWidth - 22 - 300;
58
+ boundary.bottom = systemInfo.windowHeight - 354 - 150;
59
+ this.boundary = boundary;
60
+ }
61
+ }
62
+ </script>
63
+ <style>
64
+ .boundary-box {
65
+ width: 300px;
66
+ height: 150px;
67
+ border: solid 1px red;
68
+
69
+ position: fixed;
70
+ left: 22px;
71
+ top: 354px;
72
+ }
73
+ </style>
74
+
75
+ ```
76
+
77
+ ---$
78
+ ### API
79
+ #### Props
80
+
81
+ | 参数 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
82
+ | --- | --- | --- | --- | --- | --- |
83
+ | `attract` | 是否开启自动吸边(根据 screenWidth 进行吸边) | `Boolean` | `false` | | |
84
+ | `direction` | 拖拽元素的拖拽方向限制 | `String` | `all` | `all`:不限制方向<br/>`x`:横向拖拽<br/>`y`:竖向拖拽 | |
85
+ | `boundary` | 拖拽元素的拖拽边界 默认屏幕为边界 | `Object` | `{top: 0, right: 0, bottom: 0, left: 0}` | | |
86
+
87
+
88
+ #### Events
89
+
90
+ | 事件名 | 说明 | 事件参数 | 支持版本 |
91
+ | --- | --- | --- | --- |
92
+ | `start` | 拖拽开始 | - | - |
93
+ | `end` | 拖拽结束 | - | - |
94
+
95
+
96
+ #### Slots
97
+
98
+ |插槽名 |说明 |插槽参数 |支持版本 |
99
+ | --- | --- | --- | --- |
100
+ | `default` | 拖拽内容 |- | - |
101
+
102
+ ---$
103
+ {{fuyuwei}}
@@ -0,0 +1,203 @@
1
+ <template>
2
+ <view
3
+ class="ste-drag-root"
4
+ :id="cmpRootId"
5
+ @touchstart="touchStart"
6
+ @touchmove.stop.prevent="touchMove"
7
+ @touchend="touchEnd"
8
+ @mousedown="mouseDown"
9
+ :style="{
10
+ translate: translate.x + 'px ' + translate.y + 'px',
11
+ transition: attractTransition ? 'all ease 0.3s' : 'none',
12
+ }"
13
+ >
14
+ <slot></slot>
15
+ </view>
16
+ </template>
17
+
18
+ <script>
19
+ import utils from '../../utils/utils.js';
20
+ const SCREEN_WIDTH = utils.System.getWindowWidth();
21
+ const SCREEN_HEIGHT = utils.System.getWindowHeight();
22
+ const DEFAULT_BOUNDARY = { top: 0, left: 0, right: 0, bottom: 0 };
23
+ /**
24
+ * ste-drag 拖拽
25
+ * @description 拖拽
26
+ * @tutorial https://stellar-ui.intecloud.com.cn/pc/index/index?name=ste-drag
27
+ * @property {String} attract 是否开启自动吸边(根据 screenWidth 进行吸边)默认 false
28
+ * @property {String} direction 拖拽元素的拖拽方向限制 默认 all
29
+ * @value all 不限制方向 {String}
30
+ * @value x 横向拖拽 {String}
31
+ * @value y 竖向多拽 {String}
32
+ * @property {Object} boundary 拖拽元素的拖拽边界 默认屏幕为边界
33
+ * @event {Function} start 开始拖动时触发
34
+ * @event {Function} end 结束拖动时触发
35
+ **/
36
+ export default {
37
+ group: '基础组件',
38
+ title: 'Drag 拖拽',
39
+ name: 'ste-drag',
40
+ props: {
41
+ attract: {
42
+ type: [Boolean, null],
43
+ default: false,
44
+ },
45
+ direction: {
46
+ type: [String, null],
47
+ default: 'all',
48
+ },
49
+ boundary: {
50
+ type: [Object, null],
51
+ default: () => DEFAULT_BOUNDARY,
52
+ },
53
+ },
54
+ data() {
55
+ return {
56
+ // 触摸开始位置
57
+ start: {
58
+ x: 0,
59
+ y: 0,
60
+ },
61
+ translate: { x: 0, y: 0 },
62
+ preTranslate: { x: 0, y: 0 },
63
+ attractTransition: false, // 标识是否贴边动画
64
+ initTop: 0,
65
+ initLeft: 0,
66
+ elWidth: 0,
67
+ elHeight: 0,
68
+ isMove: false,
69
+ boundaryData: this.boundary,
70
+ };
71
+ },
72
+ computed: {
73
+ cmpRootId() {
74
+ return `ste-drag-${utils.guid()}`;
75
+ },
76
+ },
77
+ mounted() {
78
+ utils.querySelector('#' + this.cmpRootId, this).then((rec) => {
79
+ this.elWidth = rec.width;
80
+ this.elHeight = rec.height;
81
+ this.initTop = rec.top;
82
+ this.initLeft = rec.left;
83
+
84
+ setTimeout(() => {
85
+ this.touchEnd();
86
+ }, 200);
87
+ });
88
+ },
89
+ watch: {
90
+ boundary: {
91
+ handler(val) {
92
+ this.boundaryData = { ...DEFAULT_BOUNDARY, ...val };
93
+ },
94
+ immediate: true,
95
+ },
96
+ },
97
+ methods: {
98
+ // #ifdef WEB
99
+ mouseDown(e) {
100
+ this.touchStart(e);
101
+ window.addEventListener('mousemove', this.touchMove);
102
+ window.addEventListener('mouseup', this.touchEnd);
103
+ },
104
+ removeListenner() {
105
+ window.removeEventListener('mousemove', this.touchMove);
106
+ window.removeEventListener('mouseup', this.touchEnd);
107
+ },
108
+ // #endif
109
+ touchStart(e) {
110
+ this.isMove = true;
111
+ this.$emit('start');
112
+ const touch = this.getMoveObj(e);
113
+ this.start = { x: touch.pageX, y: touch.pageY };
114
+ this.preTranslate = this.translate;
115
+ },
116
+ touchMove(e) {
117
+ e.preventDefault();
118
+
119
+ const touch = this.getMoveObj(e);
120
+ let x = this.preTranslate.x + (touch.pageX - this.start.x);
121
+ let xLeft = x + this.initLeft;
122
+ let y = this.preTranslate.y + (touch.pageY - this.start.y);
123
+ let yTop = y + this.initTop;
124
+
125
+ if (xLeft <= this.boundaryData.left) {
126
+ x = this.boundaryData.left - this.initLeft;
127
+ }
128
+
129
+ if (xLeft >= SCREEN_WIDTH - (this.boundaryData.right + this.elWidth)) {
130
+ x = SCREEN_WIDTH - (this.boundaryData.right + this.elWidth) - this.initLeft;
131
+ }
132
+
133
+ if (yTop <= this.boundaryData.top) {
134
+ y = this.boundaryData.top - this.initTop;
135
+ }
136
+
137
+ if (yTop >= SCREEN_HEIGHT - (this.boundaryData.bottom + this.elHeight)) {
138
+ y = SCREEN_HEIGHT - (this.boundaryData.bottom + this.elHeight) - this.initTop;
139
+ }
140
+
141
+ this.translate = {
142
+ x: this.direction == 'all' || this.direction == 'x' ? x : this.preTranslate.x,
143
+ y: this.direction == 'all' || this.direction == 'y' ? y : this.preTranslate.y,
144
+ };
145
+ },
146
+ touchEnd(e) {
147
+ this.removeListenner && this.removeListenner();
148
+ if (this.isMove) {
149
+ this.$emit('end');
150
+ this.isMove = false;
151
+ }
152
+ // 是否执行贴边
153
+ if (!this.attract) {
154
+ return;
155
+ }
156
+
157
+ let { x: moveLeft, y: moveTop } = this.translate;
158
+ const screenCenterX = (SCREEN_WIDTH - this.boundaryData.right - this.boundaryData.left) / 2;
159
+ const centerX = screenCenterX - this.initLeft - this.elWidth / 2;
160
+ if (moveLeft < centerX) {
161
+ moveLeft = this.boundaryData.left - this.initLeft;
162
+ } else {
163
+ moveLeft = SCREEN_WIDTH - this.elWidth - this.boundaryData.right - this.initLeft;
164
+ }
165
+ this.translate = { ...this.translate, x: moveLeft };
166
+
167
+ // 竖向吸边
168
+ // if (this.attractDirection == 'y') {
169
+ // const screenCenterY = (SCREEN_HEIGHT - this.boundaryData.top - this.boundaryData.bottom) / 2;
170
+ // const centerY = screenCenterY - this.initTop - this.elHeight / 2;
171
+ // if (moveTop < centerY) {
172
+ // moveTop = this.boundaryData.top - this.initTop;
173
+ // } else {
174
+ // moveTop = SCREEN_HEIGHT - this.elHeight - this.boundaryData.bottom - this.initTop;
175
+ // }
176
+ // this.translate = { ...this.translate, y: moveTop };
177
+ // } else {
178
+
179
+ // }
180
+
181
+ this.attractTransition = true;
182
+ setTimeout(() => {
183
+ this.attractTransition = false;
184
+ }, 400);
185
+ },
186
+ getMoveObj(e) {
187
+ if (e.touches?.length > 0) {
188
+ // 移动端touch事件
189
+ return { pageX: e.touches[0].pageX, pageY: e.touches[0].pageY };
190
+ } else {
191
+ // web端鼠标移动事件
192
+ return { pageX: e.pageX, pageY: e.pageY };
193
+ }
194
+ },
195
+ },
196
+ };
197
+ </script>
198
+
199
+ <style>
200
+ .ste-drag-root {
201
+ display: inline-flex;
202
+ }
203
+ </style>