oxy-uni-ui 1.2.0 → 1.2.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 (116) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +51 -1
  3. package/components/common/path.ts +9 -0
  4. package/components/common/util.ts +42 -0
  5. package/components/composables/useGlobalLoading.ts +42 -0
  6. package/components/composables/useGlobalMessage.ts +48 -0
  7. package/components/composables/useGlobalToast.ts +84 -0
  8. package/components/composables/useVirtualScroll.ts +3 -2
  9. package/components/oxy-cell/oxy-cell.vue +15 -2
  10. package/components/oxy-cell/types.ts +4 -0
  11. package/components/oxy-checkbox/index.scss +1 -1
  12. package/components/oxy-checkbox/oxy-checkbox.vue +2 -2
  13. package/components/oxy-col-picker/oxy-col-picker.vue +3 -0
  14. package/components/oxy-col-picker/types.ts +5 -1
  15. package/components/oxy-corner/oxy-corner.vue +15 -3
  16. package/components/oxy-corner/types.ts +15 -1
  17. package/components/oxy-date-strip/index.scss +10 -0
  18. package/components/oxy-date-strip/oxy-date-strip.vue +198 -0
  19. package/components/oxy-date-strip/types.ts +98 -0
  20. package/components/oxy-date-strip/utils.ts +67 -0
  21. package/components/oxy-date-strip-item/index.scss +94 -0
  22. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +102 -0
  23. package/components/oxy-date-strip-item/types.ts +53 -0
  24. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +3 -1
  25. package/components/oxy-datetime-picker/types.ts +5 -1
  26. package/components/oxy-echarts/index.scss +17 -0
  27. package/components/oxy-echarts/index.ts +1 -0
  28. package/components/oxy-echarts/oxy-echarts.vue +32 -0
  29. package/components/oxy-echarts/types.ts +12 -0
  30. package/components/oxy-file-list/index.scss +26 -0
  31. package/components/oxy-file-list/oxy-file-list.vue +208 -34
  32. package/components/oxy-file-list/types.ts +58 -2
  33. package/components/oxy-global-loading/oxy-global-loading.vue +53 -0
  34. package/components/oxy-global-message/oxy-global-message.vue +64 -0
  35. package/components/oxy-global-toast/oxy-global-toast.vue +53 -0
  36. package/components/oxy-img-lazy/index.scss +17 -0
  37. package/components/oxy-img-lazy/oxy-img-lazy.vue +332 -0
  38. package/components/oxy-img-lazy/types.ts +69 -0
  39. package/components/oxy-link/index.scss +57 -0
  40. package/components/oxy-link/oxy-link.vue +130 -0
  41. package/components/oxy-link/types.ts +81 -0
  42. package/components/oxy-list/index.scss +7 -1
  43. package/components/oxy-list/types.ts +1 -1
  44. package/components/oxy-picker/oxy-picker.vue +3 -0
  45. package/components/oxy-picker/types.ts +5 -1
  46. package/components/oxy-radio/index.scss +3 -3
  47. package/components/oxy-radio/oxy-radio.vue +1 -1
  48. package/components/oxy-rich-text/icon/emjio.svg +1 -0
  49. package/components/oxy-rich-text/icon/quote.svg +1 -0
  50. package/components/oxy-rich-text/icon/text.svg +1 -0
  51. package/components/oxy-rich-text/icon/title.svg +1 -0
  52. package/components/oxy-rich-text/index.scss +159 -0
  53. package/components/oxy-rich-text/mp-html/card/card.vue +122 -0
  54. package/components/oxy-rich-text/mp-html/card/index.js +7 -0
  55. package/components/oxy-rich-text/mp-html/editable/config.js +15 -0
  56. package/components/oxy-rich-text/mp-html/editable/index.js +553 -0
  57. package/components/oxy-rich-text/mp-html/emoji/index.js +203 -0
  58. package/components/oxy-rich-text/mp-html/highlight/config.js +5 -0
  59. package/components/oxy-rich-text/mp-html/highlight/index.js +96 -0
  60. package/components/oxy-rich-text/mp-html/highlight/prism.css +1 -0
  61. package/components/oxy-rich-text/mp-html/highlight/prism.min.js +7 -0
  62. package/components/oxy-rich-text/mp-html/img-cache/index.js +138 -0
  63. package/components/oxy-rich-text/mp-html/latex/index.js +80 -0
  64. package/components/oxy-rich-text/mp-html/latex/katex.css +1 -0
  65. package/components/oxy-rich-text/mp-html/latex/katex.min.js +1 -0
  66. package/components/oxy-rich-text/mp-html/markdown/index.js +50 -0
  67. package/components/oxy-rich-text/mp-html/markdown/marked.min.js +71 -0
  68. package/components/oxy-rich-text/mp-html/mp-html.d.ts +184 -0
  69. package/components/oxy-rich-text/mp-html/mp-html.vue +675 -0
  70. package/components/oxy-rich-text/mp-html/node/node.vue +1161 -0
  71. package/components/oxy-rich-text/mp-html/parser.js +1428 -0
  72. package/components/oxy-rich-text/mp-html/search/index.js +132 -0
  73. package/components/oxy-rich-text/mp-html/style/index.js +129 -0
  74. package/components/oxy-rich-text/mp-html/style/parser.js +175 -0
  75. package/components/oxy-rich-text/mp-html/template/index.js +67 -0
  76. package/components/oxy-rich-text/mp-html/txv-video/index.js +46 -0
  77. package/components/oxy-rich-text/oxy-rich-text.vue +642 -0
  78. package/components/oxy-rich-text/types.ts +71 -0
  79. package/components/oxy-select/index.scss +255 -0
  80. package/components/oxy-select/oxy-select.vue +421 -0
  81. package/components/oxy-select/types.ts +71 -0
  82. package/components/oxy-select-picker/oxy-select-picker.vue +3 -0
  83. package/components/oxy-select-picker/types.ts +5 -1
  84. package/components/oxy-stream-render/index.scss +6 -0
  85. package/components/oxy-stream-render/oxy-stream-render.vue +204 -0
  86. package/components/oxy-stream-render/types.ts +5 -0
  87. package/components/oxy-tree/index.scss +17 -1
  88. package/components/oxy-tree/oxy-tree.vue +89 -8
  89. package/components/oxy-tree/types.ts +11 -1
  90. package/components/oxy-waterfall/index.scss +18 -0
  91. package/components/oxy-waterfall/oxy-waterfall.vue +218 -0
  92. package/components/oxy-waterfall/types.ts +90 -0
  93. package/components/oxy-waterfall-item/index.scss +8 -0
  94. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +89 -0
  95. package/components/oxy-waterfall-item/types.ts +16 -0
  96. package/global.d.ts +7 -0
  97. package/index.ts +3 -0
  98. package/locale/lang/en-US.ts +26 -0
  99. package/locale/lang/zh-CN.ts +26 -0
  100. package/oxy-uni-ui.zip +0 -0
  101. package/package.json +1 -1
  102. package/tags.json +1 -1
  103. package/uni-echarts/changelog.md +2 -0
  104. package/uni-echarts/components/index.js +1 -0
  105. package/uni-echarts/components/uni-echarts/events.js +95 -0
  106. package/uni-echarts/components/uni-echarts/types.d.ts +183 -0
  107. package/uni-echarts/components/uni-echarts/types.js +1 -0
  108. package/uni-echarts/components/uni-echarts/uni-echarts.vue +530 -0
  109. package/uni-echarts/components/uni-echarts/uni-echarts.vue.d.ts +19 -0
  110. package/uni-echarts/global.d.ts +7 -0
  111. package/uni-echarts/index.d.ts +440 -0
  112. package/uni-echarts/index.js +2 -0
  113. package/uni-echarts/package.json +105 -0
  114. package/uni-echarts/shared-core.d.ts +269 -0
  115. package/uni-echarts/shared-core.js +900 -0
  116. package/web-types.json +1 -1
@@ -0,0 +1,255 @@
1
+ @import '../common/abstracts/variable';
2
+ @import '../common/abstracts/mixin';
3
+
4
+ @include b(select) {
5
+ display: flex;
6
+ align-items: center;
7
+ width: 100%;
8
+ flex: 1;
9
+ box-sizing: border-box;
10
+ position: relative;
11
+ .oxy-select__label {
12
+ margin: auto 0;
13
+ margin-right: $-input-cell-padding;
14
+ }
15
+ .oxy-select__icon {
16
+ position: absolute;
17
+ right: 0;
18
+ font-size: $-input-icon-size;
19
+ color: $-input-icon-color;
20
+ }
21
+ .oxy-select__icon-clear {
22
+ color: $-input-clear-color;
23
+ }
24
+ .oxy-select__icon-arrow {
25
+ transition: transform .2s;
26
+ }
27
+ .oxy-select__icon-arrow.is-open {
28
+ transform: rotate(180deg);
29
+ }
30
+ .oxy-select__box {
31
+ width: 100%;
32
+ flex: 1;
33
+ }
34
+ .oxy-select__wrapper {
35
+ font-size: $-input-fs;
36
+ border: 1px solid $-input-border-color;
37
+ box-sizing: border-box;
38
+ border-radius: 4px;
39
+ padding: 0 5px;
40
+ padding-left: $-input-cell-padding;
41
+ position: relative;
42
+ /* #ifndef APP-NVUE */
43
+ display: flex;
44
+ user-select: none;
45
+ /* #endif */
46
+ flex-direction: row;
47
+ align-items: center;
48
+ border-bottom: solid 1px $-input-border-color;
49
+ width: 100%;
50
+ flex: 1;
51
+ min-height: $-input-inner-height;
52
+
53
+ &.is-disabled {
54
+ background-color: $-input-disabled-color;
55
+ cursor: not-allowed;
56
+ }
57
+ }
58
+ .oxy-select__input-box {
59
+ width: 100%;
60
+ // height: $-input-inner-height;
61
+ position: relative;
62
+ /* #ifndef APP-NVUE */
63
+ display: flex;
64
+ /* #endif */
65
+ flex: 1;
66
+ flex-direction: row;
67
+ align-items: center;
68
+ }
69
+
70
+ .oxy-select__tags {
71
+ width: 100%;
72
+ display: flex;
73
+ flex-wrap: wrap;
74
+ &-item {
75
+ font-size: 12px;
76
+ border: 1px solid #d9ecff;
77
+ border-radius: 4px;
78
+ white-space: nowrap;
79
+ height: 24px;
80
+ padding: 0 4px;
81
+ line-height: 22px;
82
+ box-sizing: border-box;
83
+ margin: 2px 2px;
84
+ display: flex;
85
+ max-width: 100%;
86
+ align-items: center;
87
+ background-color: #f4f4f5;
88
+ border-color: #e9e9eb;
89
+ color: #909399;
90
+ &:first-child {
91
+ margin-left: 0;
92
+ }
93
+ &-text {
94
+ font-size: 12px;
95
+ white-space: nowrap;
96
+ line-height: 22px;
97
+ color: #909399;
98
+ overflow: hidden;
99
+ text-overflow: ellipsis;
100
+ }
101
+ }
102
+ .oxy-select__icon-error{
103
+ margin-left: 4px;
104
+ }
105
+ }
106
+
107
+ .oxy-select__input {
108
+ flex: 1;
109
+ font-size: 14px;
110
+ height: 22px;
111
+ line-height: 22px;
112
+ }
113
+
114
+ .oxy-select__input-plac {
115
+ color: $-input-placeholder-color;
116
+ }
117
+
118
+ .oxy-select__selector__down {
119
+ top: calc(100% + 12px);
120
+
121
+ .oxy-select__selector-arrow {
122
+ transform: rotateX(0deg);
123
+ top: -6px;
124
+ }
125
+ }
126
+
127
+ .oxy-select__selector__upwards {
128
+ bottom: calc(100% + 12px);
129
+
130
+ .oxy-select__selector-arrow {
131
+ transform: rotateX(180deg);
132
+ bottom: -6px;
133
+ }
134
+ }
135
+
136
+ .oxy-select__selector {
137
+ /* #ifndef APP-NVUE */
138
+ box-sizing: border-box;
139
+ /* #endif */
140
+ position: absolute;
141
+ left: 0;
142
+ width: 100%;
143
+ background-color: #FFFFFF;
144
+ border: 1px solid #EBEEF5;
145
+ border-radius: 6px;
146
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
147
+ z-index: 3;
148
+ padding: 4px 0;
149
+ }
150
+
151
+ .oxy-select__selector-scroll {
152
+ /* #ifndef APP-NVUE */
153
+ max-height: 200px;
154
+ box-sizing: border-box;
155
+ /* #endif */
156
+ }
157
+
158
+ .oxy-select__selector-empty,
159
+ .oxy-select__selector-item {
160
+ /* #ifndef APP-NVUE */
161
+ display: flex;
162
+ // cursor: pointer;
163
+ /* #endif */
164
+ line-height: $-input-inner-height;
165
+ font-size: 14px;
166
+ text-align: center;
167
+ padding: 0px 10px;
168
+ }
169
+
170
+ .oxy-select__selector-item {
171
+ display: flex;
172
+ justify-content: space-between;
173
+ align-items: center;
174
+ }
175
+
176
+ .oxy-select__selector-empty:last-child,
177
+ .oxy-select__selector-item:last-child {
178
+ /* #ifndef APP-NVUE */
179
+ border-bottom: none;
180
+ /* #endif */
181
+ }
182
+
183
+ .oxy-select_selector-item_active {
184
+ color: $-color-theme;
185
+ font-weight: bold;
186
+ border-radius: 3px;
187
+ }
188
+
189
+ .oxy-select__selector__disabled {
190
+ opacity: 0.4;
191
+ cursor: default;
192
+ }
193
+
194
+ /* picker 弹出层通用的指示小三角 */
195
+ .oxy-select__selector-arrow,
196
+ .oxy-select__selector-arrow::after {
197
+ position: absolute;
198
+ display: block;
199
+ width: 0;
200
+ height: 0;
201
+ border-color: transparent;
202
+ border-style: solid;
203
+ border-width: 6px;
204
+ }
205
+
206
+ .oxy-select__selector-arrow {
207
+ filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
208
+
209
+ left: 10%;
210
+ margin-right: 3px;
211
+ border-top-width: 0;
212
+ border-bottom-color: #EBEEF5;
213
+ }
214
+
215
+ .oxy-select__selector-arrow::after {
216
+ content: " ";
217
+ top: 1px;
218
+ margin-left: -6px;
219
+ border-top-width: 0;
220
+ border-bottom-color: #fff;
221
+ }
222
+
223
+ .oxy-select__input-text {
224
+ // width: 280px;
225
+ width: 90%;
226
+ color: $-input-color;
227
+ white-space: nowrap;
228
+ text-overflow: ellipsis;
229
+ -o-text-overflow: ellipsis;
230
+ overflow: hidden;
231
+ }
232
+
233
+ .oxy-select__input-selector {
234
+ position: absolute;
235
+ z-index: 1;
236
+ }
237
+
238
+ .oxy-select__input-filter {
239
+ width: auto;
240
+ margin-left: 6px;
241
+ }
242
+
243
+ .oxy-select__input-placeholder {
244
+ color: $-input-placeholder-color;
245
+ }
246
+
247
+ .oxy-select--mask {
248
+ position: fixed;
249
+ top: 0;
250
+ bottom: 0;
251
+ right: 0;
252
+ left: 0;
253
+ z-index: 2;
254
+ }
255
+ }
@@ -0,0 +1,421 @@
1
+ <template>
2
+ <view :class="`oxy-select ${customClass}`" :style="rootStyle">
3
+ <view v-if="label" class="oxy-select__label" :style="labelStyle">
4
+ <slot name="label">{{ label }}</slot>
5
+ </view>
6
+ <view class="oxy-select__box">
7
+ <view :class="['oxy-select__wrapper', { 'is-disabled': disabled, 'is-readonly': readonly }]">
8
+ <view class="oxy-select__input-box" @click="toggleSelector">
9
+ <view class="oxy-select__tags" v-if="multiple && currentList.length > 0">
10
+ <view class="oxy-select__tags-item" v-for="item in displayTags" :key="item[valueKey]">
11
+ <span class="oxy-select__tags-item-text">{{ item[labelKey] }}</span>
12
+ <view v-if="!disabled && !readonly" @click.stop="delItem(item)">
13
+ <oxy-icon custom-class="oxy-select__icon-error" name="error-fill" />
14
+ </view>
15
+ </view>
16
+ <view v-if="currentList.length > collapseTagsNum && collapseTags" class="oxy-select__tags-item">
17
+ <span class="oxy-select__tags-item-text">+{{ currentList.length - collapseTagsNum }}</span>
18
+ </view>
19
+ <input
20
+ v-if="filterable && (!disabled || !readonly)"
21
+ @input="inputChange"
22
+ class="oxy-select__input-text oxy-select__input-filter"
23
+ type="text"
24
+ placeholder="请输入"
25
+ v-model="filterInput"
26
+ />
27
+ </view>
28
+ <view v-else-if="current && current.length > 0 && !showSelector" class="oxy-select__input-text">
29
+ {{ current }}
30
+ </view>
31
+ <input
32
+ v-else-if="filterable && showSelector"
33
+ :focus="isFocus"
34
+ @input="inputChange"
35
+ :disabled="disabled"
36
+ :readonly="readonly"
37
+ class="oxy-select__input-text oxy-select__input-selector"
38
+ type="text"
39
+ :placeholder="placeholderOld"
40
+ v-model="filterInput"
41
+ />
42
+ <view v-else-if="!disabled && !readonly" class="oxy-select__input-text oxy-select__input-placeholder">{{ typePlaceholder }}</view>
43
+ <oxy-icon
44
+ v-if="(current.length > 0 && clear && !disabled && !readonly) || (currentArr.length > 0 && clear && !disabled && !readonly)"
45
+ custom-class="oxy-select__icon oxy-select__icon-clear"
46
+ name="error-fill"
47
+ @click="clearVal"
48
+ />
49
+ <oxy-icon
50
+ :custom-class="`oxy-select__icon oxy-select__icon-arrow ${showSelector ? 'is-open' : ''}`"
51
+ v-else-if="!disabled && !readonly"
52
+ name="arrow-down"
53
+ />
54
+ </view>
55
+ <oxy-transition :show="showSelector" name="fade" :duration="duration">
56
+ <view class="oxy-select--mask" @click="toggleSelector" />
57
+ <view class="oxy-select__selector" :class="isDown ? 'oxy-select__selector__down' : 'oxy-select__selector__upwards'">
58
+ <view class="oxy-select__selector-arrow"></view>
59
+ <scroll-view :scroll-y="true" class="oxy-select__selector-scroll">
60
+ <view class="oxy-select__selector-empty" v-if="filterMixinDatacomResData.length === 0">
61
+ <span>{{ emptyTips }}</span>
62
+ </view>
63
+ <view
64
+ v-else
65
+ :class="['oxy-select__selector-item', { 'oxy-select_selector-item_active': multiple && currentArr.includes(item[valueKey]) }]"
66
+ v-for="(item, index) in filterMixinDatacomResData"
67
+ :key="index"
68
+ @click="change(item)"
69
+ >
70
+ <span :class="{ 'oxy-select__selector__disabled': item.disabled }">{{ formatItemName(item) }}</span>
71
+ <oxy-icon v-if="multiple && currentArr.includes(item[valueKey])" name="check" />
72
+ </view>
73
+ </scroll-view>
74
+ </view>
75
+ </oxy-transition>
76
+ </view>
77
+ </view>
78
+ </view>
79
+ </template>
80
+ <script lang="ts">
81
+ export default {
82
+ name: 'oxy-select',
83
+ options: {
84
+ addGlobalClass: true,
85
+ virtualHost: true,
86
+ styleIsolation: 'shared'
87
+ }
88
+ }
89
+ </script>
90
+
91
+ <script lang="ts" setup>
92
+ import { getCurrentInstance, ref, watch, onMounted, computed } from 'vue'
93
+ import { objToStyle } from '../common/util'
94
+ import { selectProps, type SelectProps } from './types'
95
+ import OxyTransition from '../oxy-transition/oxy-transition.vue'
96
+
97
+ type SelectOption = Record<string, any>
98
+ type SelectModelValue = SelectProps['modelValue']
99
+
100
+ const props = defineProps(selectProps)
101
+ const emit = defineEmits(['inputChange', 'input', 'change', 'update:modelValue'])
102
+
103
+ const instance = getCurrentInstance() as any
104
+ const showSelector = ref<boolean>(false)
105
+ const current = ref<string | SelectOption[]>('')
106
+ const mixinDatacomResData = ref<SelectOption[]>([])
107
+ const placeholderOld = ref<string>('')
108
+ const currentArr = ref<Array<string | number | boolean>>([])
109
+ const filterInput = ref<string>('')
110
+ const isFocus = ref<boolean>(false)
111
+ const windowHeight = ref<number>(0)
112
+ const isDown = ref<boolean>(true)
113
+ const rootStyle = ref('')
114
+ const duration = ref<number>(200)
115
+ let overlayTimer: ReturnType<typeof setTimeout> | null
116
+
117
+ onMounted(() => {
118
+ windowHeight.value = uni.getSystemInfoSync().windowHeight
119
+ })
120
+
121
+ const labelStyle = computed(() => {
122
+ const labelStyle: Record<string, any> = {}
123
+ if (props.labelWidth) {
124
+ labelStyle['min-width'] = props.labelWidth
125
+ labelStyle['max-width'] = props.labelWidth
126
+ }
127
+ return objToStyle(labelStyle)
128
+ })
129
+
130
+ const currentList = computed(() => {
131
+ if (props.multiple && Array.isArray(current.value)) {
132
+ return current.value
133
+ }
134
+ return []
135
+ })
136
+
137
+ const displayTags = computed(() => {
138
+ if (props.collapseTags) {
139
+ return currentList.value.slice(0, props.collapseTagsNum)
140
+ }
141
+ return currentList.value
142
+ })
143
+
144
+ const filterMixinDatacomResData = computed(() => {
145
+ if (props.filterable && filterInput.value) {
146
+ return mixinDatacomResData.value.filter((e) => e[props.labelKey].includes(filterInput.value))
147
+ } else {
148
+ return mixinDatacomResData.value
149
+ }
150
+ })
151
+
152
+ const typePlaceholder = computed(() => {
153
+ return props.placeholder
154
+ })
155
+
156
+ const valueCom = computed(() => {
157
+ return props.modelValue
158
+ })
159
+
160
+ watch(
161
+ () => props.columns,
162
+ (newValue, oldValue) => {
163
+ if (Array.isArray(newValue) && oldValue !== newValue) {
164
+ mixinDatacomResData.value = newValue || []
165
+ }
166
+ },
167
+ {
168
+ immediate: true
169
+ }
170
+ )
171
+
172
+ watch(
173
+ () => valueCom.value,
174
+ () => {
175
+ initDefVal()
176
+ },
177
+ {
178
+ deep: true,
179
+ immediate: true
180
+ }
181
+ )
182
+
183
+ watch(
184
+ () => mixinDatacomResData.value,
185
+ (val) => {
186
+ if (val.length) {
187
+ initDefVal()
188
+ }
189
+ },
190
+ {
191
+ immediate: true
192
+ }
193
+ )
194
+
195
+ watch(
196
+ () => showSelector.value,
197
+ (val) => {
198
+ if (overlayTimer) {
199
+ clearTimeout(overlayTimer)
200
+ }
201
+ if (val) {
202
+ rootStyle.value = `z-index: 1;${props.customStyle}`
203
+ } else {
204
+ overlayTimer = setTimeout(() => {
205
+ rootStyle.value = `${props.customStyle}`
206
+ }, duration.value)
207
+ }
208
+ },
209
+ {
210
+ immediate: true
211
+ }
212
+ )
213
+
214
+ function getIsDown() {
215
+ const query = uni.createSelectorQuery().in(instance)
216
+ query
217
+ .select('.oxy-select__box')
218
+ .boundingClientRect((data) => {
219
+ const rect = data as UniApp.NodeInfo
220
+ if (rect && windowHeight.value - (rect.top || 0) > 200) {
221
+ isDown.value = true
222
+ } else {
223
+ isDown.value = false
224
+ }
225
+ })
226
+ .exec()
227
+ }
228
+
229
+ function initDefVal() {
230
+ let defValue: SelectModelValue | '' = ''
231
+ if ((valueCom.value || valueCom.value === 0) && !isDisabled(valueCom.value)) {
232
+ defValue = valueCom.value as SelectModelValue
233
+ } else {
234
+ let strogeValue: SelectModelValue | '' | undefined
235
+ if (strogeValue || strogeValue === 0) {
236
+ defValue = strogeValue
237
+ } else {
238
+ let defItem = ''
239
+ if (props.defItem > 0 && props.defItem <= mixinDatacomResData.value.length) {
240
+ defItem = mixinDatacomResData.value[props.defItem - 1][props.valueKey] as string
241
+ }
242
+ defValue = defItem as SelectModelValue
243
+ }
244
+ if (defValue || defValue === 0) {
245
+ handleEmit(defValue)
246
+ }
247
+ }
248
+ if (props.multiple) {
249
+ const _mixinDatacomResData = mixinDatacomResData.value || []
250
+ const defArray = Array.isArray(defValue) ? defValue : []
251
+ const list: SelectOption[] = defArray.map((item) => {
252
+ const found = _mixinDatacomResData.find((e) => {
253
+ return e[props.valueKey] == item
254
+ })
255
+ return {
256
+ ...found
257
+ }
258
+ })
259
+ current.value = list
260
+ currentArr.value = list.map((e) => e[props.valueKey] as string | number | boolean)
261
+ if (defArray.length < 1) {
262
+ currentArr.value = []
263
+ }
264
+ } else {
265
+ const def = mixinDatacomResData.value.find((item) => item[props.valueKey] === defValue)
266
+ current.value = def ? formatItemName(def) : ''
267
+ }
268
+ }
269
+
270
+ /**
271
+ * @param {[String, Number]} value
272
+ * 判断用户给的 value 是否同时为禁用状态
273
+ */
274
+ function isDisabled(value: any) {
275
+ let isDisabled = false
276
+
277
+ mixinDatacomResData.value.forEach((item) => {
278
+ if (item[props.valueKey] === value) {
279
+ isDisabled = item.disabled
280
+ }
281
+ })
282
+ return isDisabled
283
+ }
284
+
285
+ function inputChange(e: any) {
286
+ emit('inputChange', e.detail.value)
287
+ }
288
+
289
+ function clearVal() {
290
+ if (props.disabled || props.readonly) {
291
+ return
292
+ }
293
+ if (props.multiple) {
294
+ current.value = []
295
+ currentArr.value = []
296
+ handleEmit([])
297
+ } else {
298
+ current.value = ''
299
+ currentArr.value = []
300
+ handleEmit('')
301
+ }
302
+ placeholderOld.value = props.placeholder
303
+ filterInput.value = ''
304
+ }
305
+
306
+ function change(item: any) {
307
+ if (!item.disabled) {
308
+ if (props.multiple) {
309
+ if (!Array.isArray(current.value)) {
310
+ current.value = []
311
+ } else {
312
+ current.value = [...current.value]
313
+ }
314
+ const currentList = current.value as SelectOption[]
315
+ const value = item[props.valueKey] as string | number | boolean
316
+ if (!currentArr.value) {
317
+ currentArr.value = []
318
+ }
319
+ const index = currentArr.value.indexOf(value)
320
+ if (index !== -1) {
321
+ currentList.splice(index, 1)
322
+ currentArr.value.splice(index, 1)
323
+ handleEmit(currentList)
324
+ } else {
325
+ currentList.push(item)
326
+ currentArr.value.push(value)
327
+ handleEmit(currentList)
328
+ }
329
+ filterInput.value = ''
330
+ } else {
331
+ showSelector.value = false
332
+ current.value = formatItemName(item)
333
+ if (props.filterable) {
334
+ filterInput.value = item[props.labelKey]
335
+ }
336
+ handleEmit(item[props.valueKey])
337
+ }
338
+ }
339
+ }
340
+ function delItem(item: any) {
341
+ if (props.disabled || props.readonly) {
342
+ return
343
+ }
344
+ if (currentArr.value.includes(item[props.valueKey])) {
345
+ if (!Array.isArray(current.value)) {
346
+ return
347
+ }
348
+ const currentList = current.value as SelectOption[]
349
+ const index = currentList.findIndex((e) => {
350
+ return e[props.valueKey] == item[props.valueKey]
351
+ })
352
+ currentList.splice(index, 1)
353
+ currentArr.value.splice(index, 1)
354
+ handleEmit(currentList)
355
+ }
356
+ }
357
+ function handleEmit(val: any) {
358
+ if (props.multiple) {
359
+ emit('input', currentArr.value)
360
+ emit('update:modelValue', currentArr.value)
361
+ const _currentArr = mixinDatacomResData.value.filter((item) => currentArr.value.includes(item[props.valueKey]))
362
+ emit('change', _currentArr)
363
+ } else {
364
+ emit('input', val)
365
+ emit('update:modelValue', val)
366
+ const _current = mixinDatacomResData.value.find((item) => val == item[props.valueKey])
367
+ emit('change', _current)
368
+ }
369
+ }
370
+ function toggleSelector() {
371
+ if (props.disabled || props.readonly) {
372
+ return
373
+ }
374
+ getIsDown()
375
+ showSelector.value = !showSelector.value
376
+ isFocus.value = showSelector.value
377
+ if (props.filterable && current.value && showSelector.value) {
378
+ if (!props.multiple) {
379
+ if (typeof current.value === 'string') {
380
+ placeholderOld.value = current.value
381
+ }
382
+ }
383
+ } else if (props.filterable && !current.value && !showSelector.value) {
384
+ if (placeholderOld.value != props.placeholder) {
385
+ if (!props.multiple) {
386
+ current.value = placeholderOld.value
387
+ }
388
+ }
389
+ }
390
+ filterInput.value = ''
391
+ }
392
+
393
+ function formatItemName(item: any) {
394
+ if (!item) {
395
+ return ''
396
+ }
397
+ let text = item[props.labelKey]
398
+ let value = item[props.valueKey]
399
+ let { channel_code } = item
400
+ channel_code = channel_code ? `(${channel_code})` : ''
401
+ if (props.format) {
402
+ // 格式化输出
403
+ let str = ''
404
+ str = props.format
405
+ for (let key in item) {
406
+ str = str.replace(new RegExp(`{${key}}`, 'g'), item[key])
407
+ }
408
+ return str
409
+ } else {
410
+ return text ? text : `未命名${channel_code}`
411
+ }
412
+ }
413
+
414
+ // 获取当前加载的数据
415
+ function getLoadData() {
416
+ return mixinDatacomResData.value
417
+ }
418
+ </script>
419
+ <style lang="scss" scoped>
420
+ @import './index.scss';
421
+ </style>