@ecolovo/uniapp-components 1.0.10 → 2.0.1

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 (130) hide show
  1. package/README.md +202 -66
  2. package/components/aspect/aspect.vue +24 -15
  3. package/components/badge/badge.scss +20 -0
  4. package/components/badge/badge.vue +49 -40
  5. package/components/button/button.scss +15 -0
  6. package/components/button/button.vue +121 -177
  7. package/components/checkbox/checkbox.scss +10 -0
  8. package/components/checkbox/checkbox.vue +118 -146
  9. package/components/checkbox-group/checkbox-group.vue +79 -85
  10. package/components/checkbox-group2/checkbox-group2.vue +111 -107
  11. package/components/checkbox-group2/checkbox2.vue +104 -0
  12. package/components/data-list/data-list.scss +9 -0
  13. package/components/data-list/data-list.vue +70 -79
  14. package/components/date-picker/date-picker-view.vue +125 -124
  15. package/components/date-picker/date-picker.vue +145 -146
  16. package/components/dialog/dialog-content.vue +39 -47
  17. package/components/dialog/dialog.scss +11 -0
  18. package/components/dialog/dialog.vue +125 -138
  19. package/components/dropdown/dropdown.scss +11 -0
  20. package/components/dropdown/dropdown.vue +55 -97
  21. package/components/empty/empty.scss +14 -0
  22. package/components/empty/empty.vue +42 -41
  23. package/components/flex/flex.vue +45 -54
  24. package/components/form/form.vue +29 -24
  25. package/components/form-item/form-item.scss +11 -0
  26. package/components/form-item/form-item.vue +43 -40
  27. package/components/icon/icon.vue +70 -85
  28. package/components/image/image.vue +35 -38
  29. package/components/input/input.vue +65 -79
  30. package/components/input/password-input.vue +34 -42
  31. package/components/list-page/list-page.vue +73 -99
  32. package/components/load-more/load-more.scss +12 -0
  33. package/components/load-more/load-more.vue +29 -29
  34. package/components/loading/animations/loading-animation1.vue +8 -8
  35. package/components/loading/animations/loading-animation2.vue +8 -9
  36. package/components/loading/animations/loading-animation3.vue +11 -11
  37. package/components/loading/animations/loading-animation4.vue +8 -8
  38. package/components/loading/loading.vue +19 -20
  39. package/components/message-box/message-box.vue +59 -41
  40. package/components/number-dialog/number-dialog.scss +9 -0
  41. package/components/number-dialog/number-dialog.vue +209 -204
  42. package/components/number-input/number-input.scss +9 -0
  43. package/components/number-input/number-input.vue +233 -232
  44. package/components/numpad/numpad.scss +9 -0
  45. package/components/numpad/numpad.vue +133 -150
  46. package/components/page/page-body.scss +15 -0
  47. package/components/page/page-body.vue +137 -119
  48. package/components/page/page-footer.scss +13 -0
  49. package/components/page/page-footer.vue +31 -33
  50. package/components/page/page-header.scss +17 -0
  51. package/components/page/page-header.vue +89 -94
  52. package/components/page/page.scss +9 -0
  53. package/components/page/page.vue +105 -81
  54. package/components/picker/picker-popup.vue +218 -209
  55. package/components/picker/picker.vue +99 -104
  56. package/components/popover/popover-content.vue +54 -63
  57. package/components/popover/popover-mask.vue +63 -63
  58. package/components/popover/popover.scss +28 -0
  59. package/components/popover/popover.vue +49 -47
  60. package/components/popup/popup-content.vue +49 -53
  61. package/components/popup/popup.scss +11 -0
  62. package/components/popup/popup.vue +117 -132
  63. package/components/price/price.scss +20 -0
  64. package/components/price/price.vue +31 -42
  65. package/components/search/search.scss +12 -0
  66. package/components/search/search.vue +93 -117
  67. package/components/searching/searching.vue +33 -40
  68. package/components/selector/selector.vue +43 -48
  69. package/components/switch/switch.scss +12 -0
  70. package/components/switch/switch.vue +99 -96
  71. package/components/tab/tab.scss +19 -0
  72. package/components/tab/tab.vue +151 -145
  73. package/components/textarea/textarea.vue +104 -101
  74. package/composable/component-name.d.ts +2 -0
  75. package/composable/component-name.js +8 -0
  76. package/composable/component-name.ts +10 -0
  77. package/configs/index.d.ts +25 -10
  78. package/configs/index.js +14 -23
  79. package/configs/index.ts +82 -0
  80. package/easyCom.d.ts +9 -0
  81. package/easyCom.js +1 -2
  82. package/easyCom.ts +31 -0
  83. package/index.d.ts +1 -0
  84. package/index.js +1 -0
  85. package/index.ts +1 -0
  86. package/init.d.ts +4 -7
  87. package/init.js +5 -4
  88. package/init.ts +34 -0
  89. package/package.json +14 -4
  90. package/styles/utils/css-var.scss +12 -15
  91. package/styles/utils/ellipsis.scss +0 -7
  92. package/styles/utils/z-index.scss +1 -1
  93. package/styles/var/component.scss +21 -245
  94. package/utils/date.d.ts +47 -0
  95. package/utils/date.js +23 -43
  96. package/utils/date.ts +153 -0
  97. package/utils/freezeDeep.d.ts +1 -0
  98. package/utils/freezeDeep.js +4 -14
  99. package/utils/freezeDeep.ts +9 -0
  100. package/utils/price.d.ts +24 -0
  101. package/utils/price.js +14 -8
  102. package/utils/price.ts +57 -0
  103. package/utils/round.d.ts +2 -0
  104. package/utils/round.js +2 -14
  105. package/utils/round.ts +11 -0
  106. package/utils/windowInfo.d.ts +24 -0
  107. package/utils/windowInfo.js +8 -36
  108. package/utils/windowInfo.ts +50 -0
  109. package/components/checkbox-group2/checkbox.vue +0 -109
  110. package/components/datetime-picker/datetime-picker-view.vue +0 -209
  111. package/components/datetime-picker/datetime-picker.vue +0 -235
  112. package/components/form/mixin.js +0 -13
  113. package/components/list-page/list-page.js +0 -10
  114. package/components/table/table.vue +0 -112
  115. package/components/time-picker/time-picker-view.vue +0 -127
  116. package/components/time-picker/time-picker.vue +0 -140
  117. package/components/uploader/download.js +0 -81
  118. package/components/uploader/file-uploader.vue +0 -52
  119. package/components/uploader/files.js +0 -225
  120. package/components/uploader/media-uploader.vue +0 -189
  121. package/components/uploader/mixin.js +0 -171
  122. package/components/uploader/uni.js +0 -38
  123. package/components/uploader/upload-button.vue +0 -29
  124. package/components/uploader/uploader copy.vue +0 -547
  125. package/components/uploader/uploader.vue +0 -117
  126. package/mixins/componentName.js +0 -32
  127. package/mixins/listPage.js +0 -1
  128. package/mixins/windowInfo.js +0 -1
  129. package/utils/fileSize.js +0 -39
  130. package/utils/floor.js +0 -20
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view :class="componentClassNames">
2
+ <view :class="[...classNames, $style['DataList']]">
3
3
  <slot></slot>
4
4
 
5
5
  <load-more-cpn
@@ -14,98 +14,89 @@
14
14
  </view>
15
15
  </template>
16
16
 
17
- <script>
18
- import componentName from '../../mixins/componentName';
17
+ <script lang="ts" setup>
18
+ import { getCurrentInstance, onBeforeUnmount, onMounted, useCssModule, watch, WatchHandle } from 'vue';
19
+ import { PagingData } from '@ecolovo/utils/uniapp/paging';
20
+ import useClassNames from '../../composable/component-name';
19
21
  import LoadMoreCpn from '../load-more/load-more.vue';
20
22
 
21
- export default {
22
- name: 'DataList',
23
+ defineOptions({
23
24
  options: {
24
- virtualHost: true,
25
25
  styleIsolation: 'shared',
26
+ virtualHost: true,
26
27
  },
27
- components: { LoadMoreCpn },
28
- mixins: [componentName],
29
- props: {
30
- /** 是否正在加载更多数据 */
31
- loadingMore: {
32
- type: Boolean,
33
- default: false,
34
- },
35
- /** 分页大小 */
36
- pagingData: {
37
- type: Object,
38
- default: null,
39
- },
40
- /** 是否显示加载更多 */
41
- showLoadMore: {
42
- type: Boolean,
43
- default: true,
44
- },
45
- },
46
- mounted() {
47
- // 使用以下方式可持续自动触发加载更多
48
- // this._stopHasMoreWatcher = this.$watch(
49
- // 'pagingData',
50
- // () => {
51
- // this.startObserver();
52
- // },
53
- // { immediate: true, deep: true }
54
- // );
55
- this._stopHasMoreWatcher = this.$watch(
56
- 'pagingData.hasMore',
57
- (hasMore) => {
58
- if (hasMore) {
59
- this.startObserver();
60
- }
61
- },
62
- { immediate: true }
63
- );
64
- },
65
- beforeDestroy() {
66
- this.stopObserver();
67
- this._stopHasMoreWatcher?.();
68
- },
69
- methods: {
70
- startObserver() {
71
- this.stopObserver();
72
-
73
- this._observer = uni
74
- .createIntersectionObserver(this, { nativeMode: true })
75
- .relativeToViewport({
76
- bottom: 0,
77
- })
78
- .observe('.' + this.$style['DataList--observe-view'], (res) => {
79
- if (res.intersectionRatio === 0) return;
80
- this.$emit('load-more');
81
- });
82
- },
83
- stopObserver() {
84
- this._observer?.disconnect();
85
- },
86
- },
28
+ });
29
+
30
+ const classNames = useClassNames('data-list');
31
+ const $style = useCssModule();
32
+
33
+ type _Props = {
34
+ /** 是否正在加载更多数据 */
35
+ loadingMore?: boolean;
36
+ /** 分页大小 */
37
+ pagingData?: PagingData | null;
38
+ /** 是否显示加载更多 */
39
+ showLoadMore?: boolean;
87
40
  };
41
+
42
+ const props = withDefaults(defineProps<_Props>(), {
43
+ loadingMore: false,
44
+ pagingData: null,
45
+ showLoadMore: true,
46
+ });
47
+
48
+ const emit = defineEmits<{
49
+ (event: 'load-more'): void;
50
+ }>();
51
+
52
+ let _observer: UniApp.IntersectionObserver | null = null;
53
+
54
+ const vm = getCurrentInstance();
55
+
56
+ const startObserver = () => {
57
+ stopObserver();
58
+
59
+ _observer = uni.createIntersectionObserver(vm).relativeToViewport({
60
+ bottom: 0,
61
+ });
62
+ _observer.observe('.' + $style['DataList--observe-view'], (res) => {
63
+ if (res.intersectionRatio === 0) return;
64
+ emit('load-more');
65
+ });
66
+ };
67
+ const stopObserver = () => {
68
+ _observer?.disconnect();
69
+ };
70
+
71
+ let _stopHasMoreWatcher: WatchHandle | null = null;
72
+
73
+ onMounted(() => {
74
+ _stopHasMoreWatcher = watch(
75
+ () => props.pagingData?.hasMore,
76
+ (hasMore) => {
77
+ if (hasMore) {
78
+ startObserver();
79
+ }
80
+ },
81
+ { immediate: true }
82
+ );
83
+ });
84
+
85
+ onBeforeUnmount(() => {
86
+ stopObserver();
87
+ _stopHasMoreWatcher?.();
88
+ });
88
89
  </script>
89
90
 
90
91
  <style lang="scss" module>
91
- @use '../../styles/index' as *;
92
+ @use '../../styles/utils' as *;
93
+ @use './data-list' as *;
92
94
 
93
95
  // 定义外部变量
94
- $component-name: 'data-list';
95
- $component-vars: $data-list;
96
96
  %external-vars {
97
- @include UTILS__DEFINE_COMPONENT_VARS();
97
+ @include UTILS__DEFINE_COMPONENT_VARS($data-list, 'data-list');
98
98
  }
99
99
 
100
- :host {
101
- position: relative;
102
- display: block;
103
- width: 100%;
104
-
105
- flex: 1;
106
- display: flex;
107
- flex-direction: column;
108
- }
109
100
  .DataList {
110
101
  @extend %external-vars;
111
102
  flex: 1;
@@ -2,7 +2,7 @@
2
2
  <picker-view
3
3
  immediate-change
4
4
  :value="pickerValue"
5
- :class="componentClassNames"
5
+ :class="[...classNames, $style['DatePickerView']]"
6
6
  @change="handlePickerChange"
7
7
  @pickend="onPickEnd"
8
8
  >
@@ -24,149 +24,150 @@
24
24
  </picker-view>
25
25
  </template>
26
26
 
27
- <script>
27
+ <script lang="ts" setup>
28
+ import { computed, nextTick, onMounted, ref } from 'vue';
28
29
  import range from 'lodash-es/range';
29
- import componentName from '../../mixins/componentName';
30
+ import useClassNames from '../../composable/component-name';
30
31
  import { formatDate, toDate } from '../../utils/date';
31
32
 
32
- /** 年份选项 */
33
- const yearOptions = (function () {
34
- const arr = [];
33
+ defineOptions({
34
+ options: {
35
+ virtualHost: true,
36
+ styleIsolation: 'shared',
37
+ },
38
+ });
39
+
40
+ const classNames = useClassNames('date-picker-view');
41
+
42
+ /** 年份选项列表 */
43
+ const yearOptions: number[] = (function () {
44
+ const arr: number[] = [];
35
45
  for (let i = 1900; i <= 2099; i++) {
36
46
  arr.push(i);
37
47
  }
38
48
  return arr;
39
49
  })();
40
50
 
51
+ /** 月份选项列表 */
52
+ const monthOptions = range(1, 13);
53
+
41
54
  /** 获取指定日期所在月份的日期选项列表 */
42
- function getDateOptions(date) {
43
- date = new Date(date);
55
+ function getDateOptions(date: Date | number | string) {
56
+ date = new Date(toDate(date)!);
44
57
  date.setMonth(date.getMonth() + 1, 0);
45
58
  const max = date.getDate();
46
59
  return range(1, max + 1);
47
60
  }
48
61
 
49
- export default {
50
- name: 'DatePickerView',
51
- options: {
52
- virtualHost: true,
53
- styleIsolation: 'shared',
54
- },
55
- mixins: [componentName],
56
- props: {
57
- /** 绑定值 */
58
- value: {
59
- type: [String, null],
60
- default: null,
61
- },
62
- /** 最小日期 */
63
- min: {
64
- type: String,
65
- default: '',
66
- },
67
- /** 最大日期 */
68
- max: {
69
- type: String,
70
- default: '',
71
- },
72
- },
73
- data() {
74
- return {
75
- innerValue: '',
76
- /** 年份选项列表 */
77
- yearOptions: yearOptions,
78
- /** 月份选项列表 */
79
- monthOptions: range(1, 13),
80
- /** 日期选项列表 */
81
- dateOptions: [],
82
- /** picker-view 绑定值 */
83
- pickerValue: [0, 0, 0],
84
- };
85
- },
86
- computed: {
87
- currentValue: {
88
- get: function () {
89
- return this.value === null ? this.innerValue : this.value;
90
- },
91
- set: function (value) {
92
- this.$emit('input', value);
93
- this.innerValue = value;
94
- this.$emit('change', value);
95
- },
96
- },
97
- },
98
- mounted() {
99
- this.$nextTick(() => {
100
- this.syncPickerValue(this.currentValue || new Date());
101
- });
102
- },
103
- methods: {
104
- /** 同步 picker-view 选中索引 */
105
- syncPickerValue(date) {
106
- const [y, m, d] = formatDate(toDate(date)).split('-');
107
- this.dateOptions = getDateOptions(toDate(date));
108
- const i = this.yearOptions.indexOf(Number(y));
109
- const j = this.monthOptions.indexOf(Number(m));
110
- const k = this.dateOptions.indexOf(Number(d));
111
- this.$nextTick(() => {
112
- this.pickerValue =
113
- typeof this.pickerValue[0] === 'number' ? [i, j, k].map((item) => item.toString()) : [i, j, k];
114
- });
115
- },
116
- /** picker-view 选项值变化处理 */
117
- handlePickerChange(e) {
118
- const newPickerValue = e.detail.value;
119
- /** 获取变化的列 */
120
- const col = this.pickerValue.findIndex((item, index) => Number(item) !== Number(newPickerValue[index]));
121
- const year = this.yearOptions[newPickerValue[0]];
122
- const month = this.monthOptions[newPickerValue[1]];
123
- // 如果改变的是年份或月份,需要重新获取日期列表
124
- if (col === 0 || col === 1) {
125
- this.dateOptions = getDateOptions(toDate(`${year}-${month}-01`));
126
- newPickerValue[2] = Math.min(
127
- newPickerValue[2] === -1 ? this.dateOptions.length - 1 : newPickerValue[2],
128
- this.dateOptions.length - 1
129
- );
130
- }
131
- const date = this.dateOptions[newPickerValue[2]];
132
-
133
- this.pickerValue = newPickerValue;
134
- const dateValue = new Date(year, month - 1, date);
135
- let dateStr = formatDate(dateValue);
136
- if (this.min && dateStr < this.min) {
137
- let minDate;
138
-
139
- if (this.min === 'today') minDate = formatDate(new Date());
140
- else if (this.min === 'tomorrow') minDate = formatDate(new Date(Date.now() + 8.64e7));
141
- else if (this.min === 'yesterday') minDate = formatDate(new Date(Date.now() - 8.64e7));
142
- else minDate = this.min;
143
-
144
- dateStr = minDate;
145
- }
146
- if (this.max && dateStr > this.max) {
147
- let maxDate;
148
-
149
- if (this.max === 'today') maxDate = formatDate(new Date());
150
- else if (this.max === 'tomorrow') maxDate = formatDate(new Date(Date.now() + 8.64e7));
151
- else if (this.max === 'yesterday') maxDate = formatDate(new Date(Date.now() - 8.64e7));
152
- else maxDate = this.max;
153
-
154
- dateStr = maxDate;
155
- }
156
- this.currentValue = dateStr;
157
- },
158
- /** 滑动结束处理,保持选择器显示值与输入框值一致 */
159
- onPickEnd() {
160
- this.$nextTick(() => {
161
- this.syncPickerValue(this.currentValue);
162
- });
163
- },
62
+ type _Props = {
63
+ /** 绑定值 */
64
+ modelValue?: string | null;
65
+ /** 最小日期 */
66
+ min?: string;
67
+ /** 最大日期 */
68
+ max?: string;
69
+ };
70
+
71
+ const props = withDefaults(defineProps<_Props>(), {
72
+ modelValue: null,
73
+ min: '',
74
+ max: '',
75
+ });
76
+
77
+ const emit = defineEmits<{
78
+ (e: 'update:modelValue', val: string): void;
79
+ (e: 'change', val: string): void;
80
+ }>();
81
+
82
+ const innerValue = ref('');
83
+
84
+ /** 日期选项列表 */
85
+ const dateOptions = ref<number[]>([]);
86
+
87
+ /** picker-view 绑定值 */
88
+ const pickerValue = ref<number[] | string[]>([0, 0, 0]);
89
+
90
+ const currentValue = computed({
91
+ get: () => (props.modelValue === null ? innerValue.value : props.modelValue),
92
+ set: (val: string) => {
93
+ emit('update:modelValue', val);
94
+ innerValue.value = val;
95
+ emit('change', val);
164
96
  },
97
+ });
98
+
99
+ onMounted(() => {
100
+ nextTick(() => {
101
+ syncPickerValue(currentValue.value || new Date());
102
+ });
103
+ });
104
+
105
+ /** 同步 picker-view 选中索引 */
106
+ const syncPickerValue = (date: Date | number | string) => {
107
+ const [y, m, d] = formatDate(toDate(date)!).split('-');
108
+ dateOptions.value = getDateOptions(toDate(date)!);
109
+ const i = yearOptions.indexOf(Number(y));
110
+ const j = monthOptions.indexOf(Number(m));
111
+ const k = dateOptions.value.indexOf(Number(d));
112
+ nextTick(() => {
113
+ pickerValue.value =
114
+ typeof pickerValue.value[0] === 'number' ? [i, j, k].map((item) => item.toString()) : [i, j, k];
115
+ });
116
+ };
117
+
118
+ /** picker-view 选项值变化处理 */
119
+ const handlePickerChange = (e: Event) => {
120
+ const newPickerValue = (e as CustomEvent).detail.value as number[];
121
+ /** 获取变化的列 */
122
+ const col = pickerValue.value.findIndex((item, index) => Number(item) !== Number(newPickerValue[index]));
123
+ const year = yearOptions[newPickerValue[0]!]!;
124
+ const month = monthOptions[newPickerValue[1]!]!;
125
+ // 如果改变的是年份或月份,需要重新获取日期列表
126
+ if (col === 0 || col === 1) {
127
+ dateOptions.value = getDateOptions(toDate(`${year}-${month}-01`)!);
128
+ newPickerValue[2] = Math.min(
129
+ newPickerValue[2] === -1 ? dateOptions.value.length - 1 : newPickerValue[2]!,
130
+ dateOptions.value.length - 1
131
+ );
132
+ }
133
+ const date = dateOptions.value[newPickerValue[2]!];
134
+
135
+ pickerValue.value = newPickerValue;
136
+ const dateValue = new Date(year, month - 1, date);
137
+ let dateStr = formatDate(dateValue);
138
+ if (props.min && dateStr < props.min) {
139
+ let minDate: string;
140
+
141
+ if (props.min === 'today') minDate = formatDate(new Date());
142
+ else if (props.min === 'tomorrow') minDate = formatDate(new Date(Date.now() + 8.64e7));
143
+ else if (props.min === 'yesterday') minDate = formatDate(new Date(Date.now() - 8.64e7));
144
+ else minDate = props.min;
145
+
146
+ dateStr = minDate;
147
+ }
148
+ if (props.max && dateStr > props.max) {
149
+ let maxDate: string;
150
+
151
+ if (props.max === 'today') maxDate = formatDate(new Date());
152
+ else if (props.max === 'tomorrow') maxDate = formatDate(new Date(Date.now() + 8.64e7));
153
+ else if (props.max === 'yesterday') maxDate = formatDate(new Date(Date.now() - 8.64e7));
154
+ else maxDate = props.max;
155
+
156
+ dateStr = maxDate;
157
+ }
158
+ currentValue.value = dateStr;
159
+ };
160
+
161
+ /** 滑动结束处理,保持选择器显示值与输入框值一致 */
162
+ const onPickEnd = () => {
163
+ nextTick(() => {
164
+ syncPickerValue(currentValue.value);
165
+ });
165
166
  };
166
167
  </script>
167
168
 
168
169
  <style lang="scss" module>
169
- @use '../../styles/index' as *;
170
+ @use '../../styles/utils' as *;
170
171
 
171
172
  .DatePickerView {
172
173
  margin-top: 24rpx;