@weitutech/by-components 1.0.27

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,67 @@
1
+ <template>
2
+ <div class="w-full flex">
3
+ <el-input class="w-1/2" :value="value[0]" :placeholder="earliestPlaceholder" @input="(value) => handleInput(value, 'min')" @blur="(e) => handleBlur(+e.target.value, 'min')" />
4
+ <span>~</span>
5
+ <el-input class="w-1/2" :value="value[1]" :placeholder="latestPlaceholder" @input="(value) => handleInput(value, 'max')" @blur="(e) => handleBlur(+e.target.value, 'max')" />
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ export default {
11
+ props: {
12
+ value: {
13
+ type: Array,
14
+ required: true,
15
+ default: () => ["", 0]
16
+ },
17
+ earliestPlaceholder: {
18
+ type: String,
19
+ default: ""
20
+ },
21
+ latestPlaceholder: {
22
+ type: String,
23
+ default: ""
24
+ }
25
+ },
26
+
27
+ methods: {
28
+ /**
29
+ * 输入框输入回调,将其转换为数字,并反馈到父组件
30
+ * @param { string } val 输入框的value值
31
+ * @param { string } type 输入框的类型 min | max
32
+ */
33
+ handleInput(val, type) {
34
+ if (type === "min") {
35
+ const values = [val.replace(/\D+/, ""), this.value[1]]
36
+
37
+ this.$emit("input", values)
38
+ } else if (type === "max") {
39
+ const values = [this.value[0], val.replace(/\D+/, "")]
40
+
41
+ this.$emit("input", values)
42
+ }
43
+ },
44
+
45
+ /**
46
+ * 输入框失去焦点回调,判断最小输入框是否大于最大输入框和最大输入框小于最小输入框,并反馈到父组件
47
+ * @param { number } val 输入框的value值
48
+ * @param { string } type 输入框的类型 min | max
49
+ */
50
+ handleBlur(val, type) {
51
+ if (type === "min") {
52
+ if (val > this.value[1]) {
53
+ const values = [this.value[1], this.value[1]]
54
+
55
+ this.$emit("input", values)
56
+ }
57
+ } else if (type === "max") {
58
+ if (val < this.value[0]) {
59
+ const values = [this.value[0], this.value[0]]
60
+
61
+ this.$emit("input", values)
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ </script>
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <el-select
3
+ v-bind="$props"
4
+ :value="value"
5
+ ref="selection"
6
+ :placeholder="config.placeholder || '请选择'"
7
+ @change="change"
8
+ @visible-change="visibleChange"
9
+ @remove-tag="removeTag"
10
+ @clear="clear"
11
+ @blur="blur"
12
+ @focus="focus"
13
+ >
14
+ <template v-if="config.mode === 'group'">
15
+ <el-option-group
16
+ v-for="group in item.options"
17
+ :key="group[config.optionValue || 'value']"
18
+ :label="group[config.optionLabel || 'label']"
19
+ >
20
+ <el-option
21
+ v-for="gItem in group.options"
22
+ :key="gItem[config.optionValue || 'value']"
23
+ :label="gItem[config.optionLabel || 'label']"
24
+ :value="gItem[config.optionValue || 'value']"
25
+ />
26
+ </el-option-group>
27
+ </template>
28
+ <template v-else>
29
+ <el-option
30
+ v-for="(item) in filterData"
31
+ :key="item[config.optionValue || 'value'] +'-' +item[config.optionLabel || 'label']"
32
+ :label="item[config.optionLabel || 'label']"
33
+ :value="item[config.optionValue || 'value']"
34
+ />
35
+ </template>
36
+ </el-select>
37
+ </template>
38
+ <script>
39
+ import { Select } from 'element-ui'
40
+ export default {
41
+ name: 'BYSelect',
42
+ props: {
43
+ ...Select.props,
44
+ value: {
45
+ type: [String, Number, Array],
46
+ },
47
+ // 下拉框数据
48
+ placeholder: {
49
+ type: String,
50
+ default: '请选择'
51
+ },
52
+ // 下拉框数据
53
+ options: {
54
+ type: Array,
55
+ default: () => {
56
+ return []
57
+ }
58
+ },
59
+ //当前配置
60
+ config: {
61
+ type: Object,
62
+ default: null
63
+ }
64
+ },
65
+ data() {
66
+ return {
67
+ searchVal: '',
68
+ filterData: []
69
+ }
70
+ },
71
+ watch: {
72
+ options: {
73
+ handler() {
74
+ this.filterData = this.options
75
+ },
76
+ deep: true,
77
+ immediate: true
78
+ }
79
+ },
80
+ methods: {
81
+ change(e) {
82
+ this.$emit('change', arguments.length === 1 ? e : arguments)
83
+ this.$emit("input", e)
84
+ },
85
+ input(e) {
86
+ this.$emit('change', arguments.length === 1 ? e : arguments)
87
+ this.$emit("input", e)
88
+ },
89
+ visibleChange(e) {
90
+ this.$emit('visible-change', arguments.length === 1 ? e : arguments)
91
+ },
92
+ removeTag(e) {
93
+ this.$emit('remove-tag', arguments.length === 1 ? e : arguments)
94
+ },
95
+ clear(e) {
96
+ this.$emit('clear', arguments.length === 1 ? e : arguments)
97
+ },
98
+ blur(e) {
99
+ this.$emit('blur', arguments.length === 1 ? e : arguments)
100
+ },
101
+ focus(e) {
102
+ // 如果是多选模式 则做处理
103
+ if (this.multiple) {
104
+ this.searchNoReset()
105
+ }
106
+ this.$emit('blur', arguments.length === 1 ? e : arguments)
107
+ },
108
+ // 解决多选时选择后下拉数据会重置问题
109
+ searchNoReset() {
110
+ // 离开时重置数据
111
+ this.$refs.selection.$refs.input.blur = () => {
112
+ this.filterData = this.options
113
+ }
114
+
115
+ // 根据数据筛选数据
116
+ this.$refs.selection.$refs.input.onkeyup = () => {
117
+ this.filterData = this.options
118
+ this.searchVal = this.$refs.selection.$refs.input.value
119
+ this.filterData = this.options.filter(
120
+ (item) => item[this.config.optionLabel].indexOf(this.searchVal) !== -1
121
+ )
122
+ }
123
+ }
124
+ }
125
+ }
126
+ </script>
127
+
@@ -0,0 +1,352 @@
1
+ <template>
2
+ <div class="b-form">
3
+ <div class="header">
4
+ <slot name="header" />
5
+ </div>
6
+ <el-form
7
+ ref="formRef"
8
+ class="myForm"
9
+ :label-position="labelPosition"
10
+ :rules="rules"
11
+ :label-width="labelWidth"
12
+ :inline="inline"
13
+ :model="value"
14
+ label-suffix=":"
15
+ >
16
+ <el-row>
17
+ <template v-for="item in formItems">
18
+ <el-col
19
+ v-if="!item.isHidden"
20
+ v-show="showFold(item)"
21
+ :key="item.label"
22
+ v-bind="item.colLayout || colLayout"
23
+ >
24
+ <el-form-item
25
+ :label="item.label || ''"
26
+ :rules="item.rules"
27
+ :style="item.itemStyle || itemStyle"
28
+ :prop="item.field"
29
+ :label-width="item.labelWidth || labelWidth"
30
+ >
31
+ <!-- 输入框 -->
32
+ <template v-if="item.type === 'input' || item.type === 'password'">
33
+ <el-input
34
+ :placeholder="item.placeholder"
35
+ clearable
36
+ v-bind="item.otherOptions"
37
+ style="width: 100%"
38
+ :show-password="item.type === 'password'"
39
+ :value="value[`${item.field}`]"
40
+ :size="elSize"
41
+ @input="handleValueChange($event, item)"
42
+ >
43
+ <slot v-if="item.otherOptions && item.otherOptions.isPrefix" name="prefix">
44
+ <el-select
45
+ v-if="item.otherOptions.prefixType === 'select'"
46
+ slot="prepend"
47
+ :value="value[`${item.otherOptions.prefixField}`]"
48
+ placeholder="请选择"
49
+ :style="{
50
+ width: '100px'
51
+ }"
52
+ @input="handleValueChange($event, item.otherOptions)"
53
+ >
54
+ <el-option v-for="p in item.otherOptions.prefixOption" :key="p.value" :label="p.label" :value="p.value" />
55
+ </el-select>
56
+ </slot>
57
+ <slot name="suffix" />
58
+ <slot name="prepend" />
59
+ <slot name="append" />
60
+ </el-input>
61
+ </template>
62
+ <!-- 选择器 -->
63
+ <template v-else-if="item.type === 'select'">
64
+ <by-select
65
+ :value="value[`${item.field}`]"
66
+ :config="item"
67
+ v-bind="item.otherOptions"
68
+ style="width: 100%"
69
+ clearable
70
+ filterable
71
+ :size="elSize"
72
+ :options="item.options"
73
+ @input="handleValueChange($event, item)"
74
+ />
75
+ <slot :name="item.field" />
76
+ </template>
77
+ <!-- 日期选择器 -->
78
+ <template v-else-if="item.type === 'datepicker'">
79
+ <el-date-picker
80
+ style="width: 100%"
81
+ v-bind="item.otherOptions"
82
+ :placeholder="item.placeholder"
83
+ :value="value[`${item.field}`]"
84
+ :size="elSize"
85
+ @input="handleValueChange($event, item)"
86
+ />
87
+ </template>
88
+ <!-- 级联 -->
89
+ <template v-else-if="item.type === 'cascader'">
90
+ <el-cascader
91
+ style="width: 100%"
92
+ v-bind="item.otherOptions"
93
+ :placeholder="item.placeholder"
94
+ :options="item.options"
95
+ clearable
96
+ filterable
97
+ :value="value[`${item.field}`]"
98
+ :size="elSize"
99
+ @input="handleValueChange($event, item)"
100
+ />
101
+ </template>
102
+ <!-- 开关 -->
103
+ <template v-else-if="item.type === 'switch'">
104
+ <el-switch
105
+ v-bind="item.otherOptions"
106
+ :value="value[`${item.field}`]"
107
+ :size="elSize"
108
+ @input="handleValueChange($event, item)"
109
+ />
110
+ </template>
111
+ <!-- 单选框 -->
112
+ <template v-else-if="item.type === 'radioGroup'">
113
+ <el-radio-group
114
+ v-if="item.cGOptions.type === 'button'"
115
+ v-bind="item.otherOptions"
116
+ :value="value[`${item.field}`]"
117
+ :size="elSize"
118
+ @input="handleValueChange($event, item)"
119
+ >
120
+ <el-radio-button
121
+ v-for="cgb in item.cGOptions.options"
122
+ :key="cgb.value"
123
+ :label="cgb.value"
124
+ :disabled="!!cgb.disabled"
125
+ >
126
+ {{ cgb.label }}
127
+ </el-radio-button>
128
+ </el-radio-group>
129
+ <el-radio-group
130
+ v-if="item.cGOptions.type === 'checkbox'"
131
+ v-bind="item.otherOptions"
132
+ :value="value[`${item.field}`]"
133
+ :size="elSize"
134
+ @input="handleValueChange($event, item)"
135
+ >
136
+ <el-radio v-for="cg in item.cGOptions.options" :key="cg.value" :label="cg.value" :disabled="!!cg.disabled">
137
+ {{ cg.label }}
138
+ </el-radio>
139
+ </el-radio-group>
140
+ </template>
141
+ <!-- 多选框 -->
142
+ <template v-else-if="item.type === 'checkboxGroup'">
143
+ <el-checkbox-group
144
+ v-if="item.cGOptions.type === 'button'"
145
+ v-bind="item.otherOptions"
146
+ :value="value[`${item.field}`]"
147
+ :size="elSize"
148
+ @input="handleValueChange($event, item)"
149
+ >
150
+ <el-checkbox-button
151
+ v-for="cgb in item.cGOptions.options"
152
+ :key="cgb.value"
153
+ :label="cgb.value"
154
+ >
155
+ {{ cgb.label }}
156
+ </el-checkbox-button>
157
+ </el-checkbox-group>
158
+ <el-checkbox-group
159
+ v-if="item.cGOptions.type === 'checkbox'"
160
+ v-bind="item.otherOptions"
161
+ :value="value[`${item.field}`]"
162
+ :size="elSize"
163
+ @input="handleValueChange($event, item)"
164
+ >
165
+ <el-checkbox
166
+ v-for="cg in item.cGOptions.options"
167
+ :key="cg.value"
168
+ :label="cg.value"
169
+ >
170
+ {{ cg.label }}
171
+ </el-checkbox>
172
+ </el-checkbox-group>
173
+ </template>
174
+ <!-- 文本类型 -->
175
+ <template v-else-if="item.type === 'text'">
176
+ <slot :name="item.slotName">
177
+ <div>{{ `${item.defaultValue}` }}</div>
178
+ </slot>
179
+ </template>
180
+ <!-- 双数字输入框 -->
181
+ <template v-else-if="item.type === 'pairNumberInput'">
182
+ <PairNumberInput
183
+ :value="value[`${item.field}`]"
184
+ :earliest-placeholder="item.earliestPlaceholder"
185
+ :latest-placeholder="item.latestPlaceholder"
186
+ @input="handleValueChange($event, item)"
187
+ />
188
+ </template>
189
+ <!-- 时间范围自定义选择器 -->
190
+ <template v-else-if="item.type === 'customDatePicker'">
191
+ <CustomDatePicker
192
+ :value="value[`${item.field}`]"
193
+ v-bind="item"
194
+ @input="handleValueChange($event, item)"
195
+ />
196
+ </template>
197
+ <!-- 自定义 -->
198
+ <template v-else-if="item.type === 'custom'">
199
+ <slot :name="item.field" :row="item" />
200
+ </template>
201
+ <!-- 搜索按钮 -->
202
+ <template v-else-if="item.type === 'search'">
203
+ <el-button :size="elSize || 'mini'" type="primary" icon="el-icon-search" v-bind="item.otherOptions" @click="handleQueryClick">{{ (item.otherOptions || {}).text || "搜索" }}</el-button>
204
+ </template>
205
+ </el-form-item>
206
+ </el-col>
207
+ </template>
208
+ <slot name="btn" :formData="formData" />
209
+ </el-row>
210
+ </el-form>
211
+ <div class="footer">
212
+ <slot name="footer" />
213
+ </div>
214
+ </div>
215
+ </template>
216
+
217
+ <script>
218
+ import PairNumberInput from "./comps/pair-number-input.vue"
219
+ import CustomDatePicker from "./comps/custom-date-picker.vue"
220
+
221
+ export default {
222
+ name: "ByForm",
223
+ components: {
224
+ PairNumberInput,
225
+ CustomDatePicker,
226
+ },
227
+
228
+ props: {
229
+ value: {
230
+ type: Object,
231
+ required: true
232
+ },
233
+ labelPosition: {
234
+ type: String,
235
+ default: "right"
236
+ },
237
+ formItems: {
238
+ type: Array,
239
+ default: () => []
240
+ },
241
+ flexible: {
242
+ type: Object,
243
+ default: () => {
244
+ return {
245
+ foldField: "none", // 需要折叠字段
246
+ unfold: false // 默认展开?
247
+ }
248
+ }
249
+ },
250
+ labelWidth: {
251
+ type: String,
252
+ default: "100px"
253
+ },
254
+ itemStyle: {
255
+ type: Object,
256
+ default: () => ({ padding: "10px 40px" })
257
+ },
258
+ colLayout: {
259
+ type: Object,
260
+ default: () => ({
261
+ xl: 4, // >1920px 4个
262
+ lg: 6,
263
+ md: 6,
264
+ sm: 8,
265
+ xs: 12
266
+ })
267
+ },
268
+ // 是否收起
269
+ isFlexible: {
270
+ type: Boolean,
271
+ default: true
272
+ },
273
+ inline: {
274
+ type: Boolean,
275
+ default: false
276
+ },
277
+ rules: {
278
+ type: Object,
279
+ default: () => {}
280
+ },
281
+ elSize: {
282
+ type: String,
283
+ default: "mini"
284
+ }
285
+ },
286
+
287
+ data() {
288
+ return {
289
+ formData: this.value,
290
+ // 数据替换
291
+ replacementData: undefined
292
+ }
293
+ },
294
+
295
+ computed: {
296
+ showFold() {
297
+ return (item) => {
298
+ if (this.isFlexible) {
299
+ return true
300
+ } else {
301
+ if (this.flexible && this.flexible.foldField.length) {
302
+ if (this.flexible.foldField.includes(item.id) || this.flexible.foldField.includes(item.field)) {
303
+ return false
304
+ } else {
305
+ return true
306
+ }
307
+ } else {
308
+ return true
309
+ }
310
+ }
311
+ }
312
+ }
313
+ },
314
+
315
+ watch: {
316
+ value: {
317
+ handler(newValue, oldValue) {
318
+ this.formData = newValue
319
+ this.replacementData = {
320
+ ...(this.replacementData ? this.replacementData : {}),
321
+ ...newValue
322
+ }
323
+ },
324
+ deep: true,
325
+ immediate: true
326
+ }
327
+ },
328
+
329
+ methods: {
330
+ validate(cb = () => {}) {
331
+ this.$refs.formRef.validate((valid, obj) => {
332
+ cb(valid, obj)
333
+ })
334
+ },
335
+ clearValidate() {
336
+ this.$refs.formRef.clearValidate()
337
+ },
338
+ handleValueChange(value, item) {
339
+ if (this.replacementData) {
340
+ this.replacementData[item.field] = value
341
+ } else {
342
+ this.replacementData = { ...this.value, [item.field]: value }
343
+ }
344
+ this.$emit("change", { ...item, value })
345
+ this.$emit("input", this.replacementData)
346
+ },
347
+ handleQueryClick() {
348
+ this.$emit("queryBtnClick")
349
+ }
350
+ }
351
+ }
352
+ </script>
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <div class="b-page-search">
3
+ <by-form
4
+ :value="formData"
5
+ v-bind="searchFormConfig"
6
+ :is-flexible="unfold"
7
+ @input="handleInput"
8
+ @change="handleChange"
9
+ @queryBtnClick="handleQueryClick"
10
+ >
11
+ <template #header>
12
+ <slot name="header" />
13
+ </template>
14
+ <template #footer>
15
+ <div v-if="isShowUnfoldBtn" class="fold">
16
+ <by-fold-search @change="handleFlexible" />
17
+ </div>
18
+ </template>
19
+ <template v-for="item in getCustomItem" #[item]>
20
+ <slot :name="item" />
21
+ </template>
22
+ </by-form>
23
+ </div>
24
+ </template>
25
+
26
+ <script>
27
+
28
+ export default {
29
+ props: {
30
+ searchFormConfig: {
31
+ type: Object,
32
+ required: true,
33
+ default: () => {}
34
+ },
35
+ value: {
36
+ type: Object,
37
+ default: () => {}
38
+ }
39
+ },
40
+
41
+ data() {
42
+ return {
43
+ formItems: this.searchFormConfig?.formItems ?? [],
44
+ formOriginData: {}, // 最初的初始化数据
45
+ formData: {}, // 双向绑定的
46
+ unfold: false // 是否展开
47
+ }
48
+ },
49
+
50
+ computed: {
51
+ isShowUnfoldBtn() {
52
+ const formItems = this.searchFormConfig?.formItems ?? []
53
+ const flexible = this.searchFormConfig?.flexible ?? undefined
54
+ // 如果没有配置flexible, 则默认为true
55
+ if (flexible) {
56
+ if (formItems.length > flexible.foldField.length) {
57
+ return true
58
+ } else {
59
+ return false
60
+ }
61
+ } else {
62
+ return false
63
+ }
64
+ },
65
+ // 所有需要自定义的插槽
66
+ getCustomItem() {
67
+ return this.formItems.filter(f => f.type === "custom").map(item => item.field)
68
+ }
69
+ },
70
+
71
+ watch: {
72
+ value: {
73
+ handler(newValue, oldValue) {
74
+ this.formData = newValue
75
+ },
76
+ deep: true,
77
+ immediate: true
78
+ }
79
+ },
80
+
81
+ mounted() {
82
+ this.formOriginData = this.value
83
+ this.unfold = this.searchFormConfig.flexible?.unfold ?? false
84
+ },
85
+
86
+ // 双向绑定的属性应该是由配置文件的field来决定
87
+ // 1.优化一: formData中的属性应该动态来决定
88
+ methods: {
89
+ // 2.优化二: 当用户点击重置
90
+ handleResetClick() {
91
+ this.formData = { ...this.formOriginData }
92
+ this.$emit("input", { ...this.formOriginData })
93
+ this.$emit("resetBtnClick")
94
+ },
95
+
96
+ // 3.优化三: 当用户点击搜索
97
+ handleQueryClick() {
98
+ this.$emit("queryBtnClick")
99
+ },
100
+
101
+ // 4.优化四: 当用户点击展开
102
+ handleFlexible() {
103
+ this.unfold = !this.unfold
104
+ },
105
+ handleInput(value) {
106
+ this.formData = value
107
+ this.$emit("input", { ...this.formData })
108
+ },
109
+ handleChange(event) {
110
+ this.$emit("change", event)
111
+ }
112
+ }
113
+ }
114
+ </script>