@kaiyinchem/ky-uniui 1.0.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.
@@ -0,0 +1,232 @@
1
+ <template>
2
+ <view class="count-num" :class="size" @click="$emit('click')">
3
+ <text
4
+ :class="{ disabled: disabled || Number(count) <= Number(min) }"
5
+ class="iconfont cn-min"
6
+ @click.stop="countNum(0)"
7
+ >
8
+ &#xe643;
9
+ </text>
10
+ <input
11
+ type="digit"
12
+ :disabled="disabled"
13
+ :focus="focus"
14
+ :class="{disabled}"
15
+ :cursor-spacing="20"
16
+ class="cn-count"
17
+ v-model="count"
18
+ @blur="onInput"
19
+ @focus="onFocus"
20
+ />
21
+ <text
22
+ :class="{ disabled: disabled || Number(count) >= Number(max) }"
23
+ class="iconfont cn-add"
24
+ @click.stop="countNum(1)"
25
+ >
26
+ &#xe611;
27
+ </text>
28
+ </view>
29
+ </template>
30
+
31
+ <script>
32
+ export default {
33
+ emits: ['update:value'],
34
+ props: {
35
+ value: {
36
+ type: [Number, String],
37
+ default: 0
38
+ },
39
+ max: {
40
+ type: [Number, String],
41
+ default: 9999999
42
+ },
43
+ min: {
44
+ type: [Number, String],
45
+ default: 0
46
+ },
47
+ disabled: {
48
+ type: Boolean,
49
+ default: false
50
+ },
51
+ // 是否倍数递增
52
+ multiple: {
53
+ type: Boolean,
54
+ default: false
55
+ },
56
+ focus: {
57
+ type: Boolean,
58
+ default: false,
59
+ },
60
+ size: {
61
+ type: String,
62
+ default: 'small', // small, large
63
+ },
64
+ step: {
65
+ type: Number,
66
+ default: 1
67
+ }
68
+ },
69
+ data() {
70
+ return {
71
+ count: 1,
72
+ isErrorNumber: false,
73
+ }
74
+ },
75
+ watch: {
76
+ value(v) {
77
+ this.count = v
78
+ }
79
+ },
80
+ mounted() {
81
+ this.count = this.value || this.min
82
+
83
+ // 如果是按倍数,最大数值自动乘以1000
84
+ // if (this.multiple) {
85
+ // this.max = this.min * 1000
86
+ // }
87
+ },
88
+ methods: {
89
+ onFocus() {
90
+ this.isFocus = true
91
+ },
92
+ onInput() {
93
+ const max = Number(this.max)
94
+ const count = Number(this.count)
95
+ const min = Number(this.min)
96
+
97
+ if (!this.isFocus) {
98
+ return
99
+ }
100
+ this.isFocus = false
101
+
102
+ // 如果输入的不是倍数,自动调整成最小的数值
103
+ if (this.multiple) {
104
+ if (count % min !== 0) {
105
+ this.count = min
106
+ this.$toast('请输入规格的倍数')
107
+ }
108
+ this.emit()
109
+ } else {
110
+ if (count < min) {
111
+ this.$toast('超出最小数值')
112
+ }
113
+
114
+ if (count > max) {
115
+ this.$toast('超出最大数值')
116
+ }
117
+ this.emit()
118
+ }
119
+ },
120
+ countNum(isAdd) {
121
+ const max = +this.max
122
+ const min = +this.min
123
+ this.count = +this.count
124
+ if (this.multiple && Number.isNaN(min)) {
125
+ this.$toast('数量异常')
126
+ return
127
+ }
128
+
129
+ if (this.multiple && this.count % min !== 0) {
130
+ this.count = min
131
+ this.$toast('只能是规格的倍数')
132
+ this.emit()
133
+ return
134
+ }
135
+
136
+ if (this.disabled) {
137
+ this.emit()
138
+ return
139
+ }
140
+ if (isAdd) {
141
+ if (this.count >= max) {
142
+ return
143
+ }
144
+ this.count = this.multiple ? this.count += min : this.count + Number(this.step)
145
+ this.emit()
146
+ } else {
147
+ if (this.count <= min) {
148
+ return
149
+ }
150
+ this.count = this.multiple ? this.count -= min : this.count - Number(this.step)
151
+ this.emit()
152
+ }
153
+ },
154
+ emit() {
155
+ const count = this.multiple ? Number(this.count).toFixed(3) : this.count
156
+ this.$emit('update:value', Number(count))
157
+ }
158
+ }
159
+ }
160
+ </script>
161
+
162
+ <style scoped lang="scss">
163
+ .count-num {
164
+ display: flex;
165
+ border: 1px solid var(--border-1);;
166
+ border-radius: 6rpx;
167
+ align-items: center;
168
+ overflow: hidden;
169
+ &.large {
170
+ .cn-count {
171
+ height: 65rpx;
172
+ }
173
+ .iconfont {
174
+ width: 65rpx;
175
+ height: 65rpx;
176
+ line-height: 65rpx;
177
+ }
178
+ }
179
+
180
+ .iconfont {
181
+ text-align: center;
182
+ font-size: 26rpx;
183
+ color: var(--color-gray);
184
+ display: block;
185
+ width: 52rpx;
186
+ height: 52rpx;
187
+ line-height: 52rpx;
188
+ background: var(--border-1);
189
+
190
+ &:active {
191
+ background: var(--bg-gray);
192
+ }
193
+
194
+ &.disabled {
195
+ color: var(--color-light-gray);
196
+ background: rgba(var(--rgb-light-gray), 0.2);
197
+
198
+ &:active {
199
+ background: rgba(var(--rgb-light-gray), 0.2);
200
+ }
201
+ }
202
+ }
203
+
204
+ .cn-min {
205
+ border-top-left-radius: 6rpx;
206
+ border-bottom-left-radius: 6rpx;
207
+ }
208
+
209
+ .cn-add {
210
+ border-top-right-radius: 6rpx;
211
+ border-bottom-right-radius: 6rpx;
212
+ }
213
+
214
+ .cn-count {
215
+ text-align: center;
216
+ min-width: 100rpx;
217
+ font-size: 28rpx;
218
+ height: 52rpx;
219
+ flex: 1;
220
+ background: var(--bg-wite);
221
+ &.disabled {
222
+ color: var(--color-light-gray);
223
+ background: rgba(var(--rgb-light-gray), 0.2);
224
+ }
225
+ }
226
+ }
227
+ @media (prefers-color-scheme: dark) {
228
+ .count-num .cn-count {
229
+ background: #222222;
230
+ }
231
+ }
232
+ </style>
@@ -0,0 +1,130 @@
1
+ <!--简易的数字递增组件,没有动画效果,纯粹递增, 2021-12-20 zzc-->
2
+ <template>
3
+ <view class="ky-countto-number">
4
+ <template v-if="value">
5
+ <text
6
+ v-for="(item, index) in splitNumber"
7
+ :key="index"
8
+ :style="itemStyle"
9
+ :class="{ notNum: typeof item !== 'number' }"
10
+ class="ky-countto-number-item"
11
+ >
12
+ {{ item }}
13
+ </text>
14
+ </template>
15
+ <text v-else class="ky-countto-number-item">0</text>
16
+ <text v-if="suffix && !$slots.suffix" class="ky-countto-number-item ky-countto-suffix ft-24">{{ suffix }}</text>
17
+ <slot name="suffix"></slot>
18
+ </view>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ emits: ['update:value'],
24
+ props: {
25
+ value: {
26
+ type: [String, Number],
27
+ default: ''
28
+ },
29
+ multiple: {
30
+ type: Boolean,
31
+ default: false
32
+ },
33
+ itemStyle: {
34
+ type: Object,
35
+ defatlt: () => {
36
+ return {
37
+ width: '22rpx'
38
+ }
39
+ }
40
+ },
41
+ suffix: {
42
+ type: String,
43
+ default: ''
44
+ },
45
+ },
46
+ data() {
47
+ return {
48
+ splitNumber: [],
49
+ timer: ''
50
+ }
51
+ },
52
+ watch: {
53
+ value(v) {
54
+ this.startCount(v)
55
+ }
56
+ },
57
+ mounted() {
58
+ this.startCount(this.value)
59
+ },
60
+ destroyed() {
61
+ clearTimeout(this.timer)
62
+ this.timer = ''
63
+ },
64
+ methods: {
65
+ startCount(value) {
66
+ if (!value) {
67
+ return
68
+ }
69
+ clearTimeout(this.timer)
70
+ this.timer = ''
71
+ const target = String(value).split('').map(e => {
72
+ if (e !== '.') {
73
+ e = +e
74
+ }
75
+ return e
76
+ })
77
+ this.splitNumber = target.map(e => {
78
+ if (e !== '.') {
79
+ e = 0
80
+ }
81
+ return e
82
+ })
83
+ const len = this.splitNumber.length - 1
84
+ const last = []
85
+ // 递归循环
86
+ const loop = (index) => {
87
+ this.timer = setTimeout(() => {
88
+
89
+ if (this.splitNumber[index] >= target[index]) {
90
+ if (index <= 0) {
91
+ clearTimeout(this.timer)
92
+ this.timer = ''
93
+ return
94
+ }
95
+ index --
96
+ }
97
+
98
+ if (target[index] === 0 || target[index] === '.') {
99
+ index --
100
+ }
101
+
102
+ if (target[index] !== 0 && target[index] !== '.') {
103
+ this.splitNumber[index] ++
104
+ }
105
+
106
+ loop(index)
107
+ }, 50)
108
+ }
109
+ loop(len)
110
+ },
111
+ }
112
+ }
113
+ </script>
114
+
115
+ <style scoped lang="scss">
116
+ .ky-countto-number {
117
+ .ky-countto-number-item {
118
+ display: inline-block;
119
+ color: inherit;
120
+ width: 22rpx;
121
+ &.notNum {
122
+ width: auto!important;
123
+ }
124
+ }
125
+ .ky-countto-suffix {
126
+ font-weight: normal;
127
+ }
128
+ }
129
+
130
+ </style>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <view class="ky-empty-wrap">
3
+ <view class="ky-empty-box">
4
+ <image v-if="icon" class="ky-empty-icon" src="/static/img/nodata.png"></image>
5
+ <text v-if="msg" class="ky-empty-msg">{{ msg }}</text>
6
+ <slot></slot>
7
+ </view>
8
+ </view>
9
+ </template>
10
+
11
+ <script>
12
+ export default {
13
+ props: {
14
+ icon: {
15
+ type: Boolean,
16
+ default: true
17
+ },
18
+ msg: {
19
+ type: String,
20
+ default: '暂无数据'
21
+ },
22
+ },
23
+ data() {
24
+ return {
25
+
26
+ }
27
+ }
28
+ }
29
+ </script>
30
+
31
+ <style scoped lang="scss">
32
+ .ky-empty-wrap {
33
+ display: flex;
34
+ justify-content: center;
35
+ padding: 48rpx;
36
+ .ky-empty-box {
37
+ display: flex;
38
+ flex-direction: column;
39
+ justify-content: center;
40
+ align-items: center;
41
+ }
42
+ .ky-empty-icon {
43
+ width: 146rpx;
44
+ height: 146rpx;
45
+ }
46
+ .ky-empty-msg {
47
+ display: inline-block;
48
+ margin-bottom: 24rpx;
49
+ font-size: 28rpx;
50
+ color: #999999;
51
+ }
52
+ }
53
+ </style>