fit2cloud-ui-plus 0.0.1-beta.0

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 (89) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +16 -0
  3. package/lib/favicon.bmp +0 -0
  4. package/lib/fit2cloud-ui-plus.es.js +3796 -0
  5. package/lib/fit2cloud-ui-plus.umd.js +1 -0
  6. package/package.json +48 -0
  7. package/src/components/filter-bar/FuFilter.vue +175 -0
  8. package/src/components/filter-bar/FuFilterBar.vue +75 -0
  9. package/src/components/filter-bar/FuFilterConditions.vue +29 -0
  10. package/src/components/filter-bar/FuSearchInput.vue +31 -0
  11. package/src/components/filter-bar/filter-components/FuFilterDate.vue +62 -0
  12. package/src/components/filter-bar/filter-components/FuFilterDateTime.vue +65 -0
  13. package/src/components/filter-bar/filter-components/FuFilterOption.vue +38 -0
  14. package/src/components/filter-bar/filter-components/FuFilterSelect.vue +143 -0
  15. package/src/components/filter-bar/index.ts +19 -0
  16. package/src/components/filter-bar/types.ts +31 -0
  17. package/src/components/read-write-switch/FuInputRwSwitch.vue +44 -0
  18. package/src/components/read-write-switch/FuReadWriteSwitch.vue +91 -0
  19. package/src/components/read-write-switch/FuSelectRwSwitch.vue +53 -0
  20. package/src/components/read-write-switch/index.ts +13 -0
  21. package/src/components/search-bar/FuComplexSearch.vue +108 -0
  22. package/src/components/search-bar/FuQuickSearch.vue +43 -0
  23. package/src/components/search-bar/FuSearchBar.vue +165 -0
  24. package/src/components/search-bar/FuSearchBarButton.vue +14 -0
  25. package/src/components/search-bar/FuSearchContions.vue +24 -0
  26. package/src/components/search-bar/index.ts +13 -0
  27. package/src/components/search-bar/store.ts +25 -0
  28. package/src/components/speed-dial/FuSpeedDial.vue +280 -0
  29. package/src/components/speed-dial/FuSpeedDialActionButton.vue +88 -0
  30. package/src/components/speed-dial/FuSpeedDialButton.vue +42 -0
  31. package/src/components/speed-dial/FuSpeedDialItem.vue +88 -0
  32. package/src/components/speed-dial/index.ts +11 -0
  33. package/src/components/split-pane/FuSplitPane.vue +228 -0
  34. package/src/components/split-pane/index.ts +8 -0
  35. package/src/components/steps/FuHorizontalNavigation.vue +18 -0
  36. package/src/components/steps/FuHorizontalSteps.vue +94 -0
  37. package/src/components/steps/FuStep.vue +13 -0
  38. package/src/components/steps/FuSteps.vue +22 -0
  39. package/src/components/steps/FuStepsFooter.ts +79 -0
  40. package/src/components/steps/FuVerticalNavigation.vue +35 -0
  41. package/src/components/steps/FuVerticalSteps.vue +79 -0
  42. package/src/components/steps/Stepper.ts +188 -0
  43. package/src/components/steps/index.ts +11 -0
  44. package/src/components/table/FuTable.vue +145 -0
  45. package/src/components/table/FuTableBody.ts +40 -0
  46. package/src/components/table/FuTablePagination.vue +42 -0
  47. package/src/components/table/index.ts +15 -0
  48. package/src/components/table/table-column-dropdown/FuTableColumnDropdown.vue +102 -0
  49. package/src/components/table/table-column-dropdown/index.ts +7 -0
  50. package/src/components/table/table-column-select/FuTableColumnSelect.vue +22 -0
  51. package/src/components/table/table-column-select/FuTableColumnSelectDialog.vue +99 -0
  52. package/src/components/table/table-column-select/FuTableColumnSelectPopover.vue +80 -0
  53. package/src/components/table/table-column-select/index.ts +8 -0
  54. package/src/components/table/table-column-select/utils.ts +59 -0
  55. package/src/components/table/table-operations/FuTableButton.vue +19 -0
  56. package/src/components/table/table-operations/FuTableMoreButton.vue +52 -0
  57. package/src/components/table/table-operations/FuTableOperations.vue +88 -0
  58. package/src/components/table/table-operations/index.ts +12 -0
  59. package/src/components/tabs/FuTabs.vue +84 -0
  60. package/src/components/tabs/index.ts +8 -0
  61. package/src/components/virtual-scroller/FuVirtualHorizontalScroll.js +96 -0
  62. package/src/components/virtual-scroller/FuVirtualScroll.js +15 -0
  63. package/src/components/virtual-scroller/FuVirtualVerticalScroll.js +95 -0
  64. package/src/components/virtual-scroller/index.js +10 -0
  65. package/src/hooks/index.ts +3 -0
  66. package/src/hooks/use-global-config/index.ts +32 -0
  67. package/src/hooks/use-locale/index.ts +47 -0
  68. package/src/index.ts +19 -0
  69. package/src/locale/index.ts +12 -0
  70. package/src/locale/lang/en.ts +58 -0
  71. package/src/locale/lang/zh-cn.ts +58 -0
  72. package/src/locale/lang/zh-tw.ts +58 -0
  73. package/src/styles/common/config.scss +5 -0
  74. package/src/styles/common/function.scss +81 -0
  75. package/src/styles/common/mixins.scss +85 -0
  76. package/src/styles/common/variables.scss +28 -0
  77. package/src/styles/components/filter-bar.scss +227 -0
  78. package/src/styles/components/read-write-switch.scss +6 -0
  79. package/src/styles/components/search-bar.scss +285 -0
  80. package/src/styles/components/speed-dial.scss +107 -0
  81. package/src/styles/components/split-pane.scss +111 -0
  82. package/src/styles/components/steps.scss +110 -0
  83. package/src/styles/components/table.scss +105 -0
  84. package/src/styles/components/tabs.scss +10 -0
  85. package/src/styles/components/virtual-scroller.scss +24 -0
  86. package/src/styles/index.scss +11 -0
  87. package/src/tools/theme.ts +23 -0
  88. package/src/tools/time.ts +30 -0
  89. package/src/tools/utils.ts +60 -0
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <div class="fu-filter-component">
3
+ <div class="fu-filter-component__label">{{ label }}</div>
4
+ <div class="fu-filter-component__content">
5
+ <!-- :size="configSize" -->
6
+ <el-date-picker class="fu-filter-date" v-model="value" v-bind="$attrs"
7
+ :placeholder="t('fu.search_bar.select_date_time')" type="datetimerange"
8
+ :value-format="valueFormat"
9
+ :start-placeholder="t('fu.search_bar.start_date_time')"
10
+ :end-placeholder="t('fu.search_bar.end_date_time')">
11
+ </el-date-picker>
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script setup lang="ts">
17
+ import {ref, computed, inject} from "vue";
18
+ import {FilterCondition, ReferenceContext, referenceKey} from "../types";
19
+ import {datetimeFormat} from "@/tools/time";
20
+ import {useLocale} from "@/hooks"
21
+ defineOptions({ name: "FuFilterDateTime" });
22
+ const {t} = useLocale()
23
+
24
+ const props = defineProps({
25
+ label: String,
26
+ field: {
27
+ type: String,
28
+ required: true
29
+ },
30
+ valueFormat: {
31
+ type: String,
32
+ default: "x",
33
+ },
34
+ })
35
+
36
+ const value = ref('')
37
+
38
+ const valueLabel = computed(() => {
39
+ return (
40
+ datetimeFormat(value.value[0]) +
41
+ " - " +
42
+ datetimeFormat(value.value[1])
43
+ );
44
+ })
45
+
46
+ function getCondition(): FilterCondition | undefined {
47
+ if (!String(value.value)) return;
48
+ let {field, label} = props
49
+ return {field, label, value: value.value, valueLabel: valueLabel.value}
50
+ }
51
+
52
+ function init(v: any) {
53
+ value.value = v !== undefined ? v : ''
54
+ }
55
+
56
+ const references = inject(referenceKey)
57
+ const field = props.field
58
+ const reference: ReferenceContext = {field, init, getCondition}
59
+ references?.value.push(reference)
60
+
61
+ defineExpose({
62
+ getCondition,
63
+ init
64
+ })
65
+ </script>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <div class="fu-filter-option" :class="{ 'is-selected': selected, 'is-disabled': disabled }" @click.stop="click">
3
+ {{ label || value }}
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import {computed, inject} from "vue";
9
+ import {selectKey} from "@/components/filter-bar/types";
10
+
11
+ const props = defineProps({
12
+ value: {
13
+ type: [String, Number],
14
+ required: true
15
+ },
16
+ label: [String, Number],
17
+ disabled: {
18
+ type: Boolean,
19
+ default: false
20
+ }
21
+ })
22
+
23
+ const select = inject(selectKey)
24
+
25
+ const selected = computed(() => {
26
+ if (!select) return false
27
+ if (Array.isArray(select.selection.value)) {
28
+ return select.selection.value.includes(props.value)
29
+ } else {
30
+ return select.selection.value === props.value
31
+ }
32
+ })
33
+
34
+ function click() {
35
+ select?.setSelected(props.value, selected.value)
36
+ }
37
+
38
+ </script>
@@ -0,0 +1,143 @@
1
+ <template>
2
+ <div class="fu-filter-component">
3
+ <div class="fu-filter-component__label">{{ label }}</div>
4
+ <div class="fu-filter-component__content">
5
+ <fu-filter-option :label="o.label" :value="o.value" v-for="o in showOptions" :key="o.value"/>
6
+ <el-popover popper-class="fu-filter-component-popover" :show-arrow="false" placement="bottom-start"
7
+ trigger="click" width="240">
8
+ <el-select v-model="selection" v-bind="$attrs" :multiple="multiple" @change="change" :teleported="false"
9
+ :placeholder="t('fu.search_bar.please_select')">
10
+ <el-option value="" v-if="useSelectAll && multiple">
11
+ <div @click="selectAll">{{ t('fu.filter_bar.select_all') }}</div>
12
+ </el-option>
13
+ <el-option :label="o.label" :value="o.value" v-for="o in options" :key="o.value"/>
14
+ </el-select>
15
+ <template #reference>
16
+ <div class="fu-filter-option">
17
+ <el-icon>
18
+ <Plus/>
19
+ </el-icon>
20
+ {{ t('fu.filter_bar.more') }}
21
+ </div>
22
+ </template>
23
+ </el-popover>
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import {ref, provide, computed, PropType, Ref, inject} from "vue";
30
+ import FuFilterOption from "./FuFilterOption.vue";
31
+ import {FilterCondition, OptionProps, ReferenceContext, referenceKey, selectKey} from "../types";
32
+
33
+ import {useLocale} from "@/hooks"
34
+ defineOptions({ name: "FuFilterSelect" });
35
+ const {t} = useLocale()
36
+
37
+ const props = defineProps({
38
+ multiple: {
39
+ type: Boolean,
40
+ default: false
41
+ },
42
+ showLimit: {
43
+ type: Number,
44
+ default: 3 // -1 全显示
45
+ },
46
+ useSelectAll: {
47
+ type: Boolean,
48
+ default: false
49
+ },
50
+ label: String,
51
+ field: {
52
+ type: String,
53
+ required: true
54
+ },
55
+ options: {
56
+ type: Array as PropType<OptionProps[]>,
57
+ default: []
58
+ }
59
+ })
60
+ const emit = defineEmits(["change"])
61
+
62
+ const selection: Ref<Array<string | number> | string | number> = ref(props.multiple ? [] : '')
63
+
64
+ const showOptions = computed(() => {
65
+ return props.options.filter((o, i) => {
66
+ let show = props.showLimit < 0 ? true : i < props.showLimit
67
+ if (Array.isArray(selection.value)) {
68
+ return show || selection.value.includes(o.value)
69
+ } else {
70
+ return show || selection.value === o.value
71
+ }
72
+ })
73
+ })
74
+
75
+ const valueLabel = computed(() => {
76
+ if (Array.isArray(selection.value)) {
77
+ let values: any = []
78
+ selection.value.forEach((v: any) => {
79
+ values.push(getValueLabel(v))
80
+ })
81
+ return values.join(", ");
82
+ }
83
+ return getValueLabel(selection.value);
84
+ })
85
+
86
+ function change(v: string) {
87
+ if (v.includes("")) {
88
+ selection.value = props.options.map(o => o.value)
89
+ }
90
+ emit("change", selection.value)
91
+ }
92
+
93
+ function setSelected(value: string | number, selected: boolean) {
94
+ if (!Array.isArray(selection.value)) {
95
+ selection.value = selected ? '' : value
96
+ return
97
+ }
98
+ if (selected) {
99
+ let index = selection.value.indexOf(value)
100
+ selection.value.splice(index, 1)
101
+ } else {
102
+ selection.value.push(value)
103
+ }
104
+ }
105
+
106
+ function selectAll() {
107
+ selection.value = props.options.map(o => o.value)
108
+ }
109
+
110
+ function getValueLabel(value: string | number) {
111
+ for (let o of props.options) {
112
+ if (o.value === value) {
113
+ return o.label
114
+ }
115
+ }
116
+ return value
117
+ }
118
+
119
+ function getCondition(): FilterCondition | undefined {
120
+ if (!selection.value || (Array.isArray(selection.value) && selection.value.length === 0)) return;
121
+ let {field, label} = props
122
+ return {field, label, value: selection.value, valueLabel: valueLabel.value}
123
+ }
124
+
125
+ function init(v: any) {
126
+ selection.value = v !== undefined ? v : props.multiple ? [] : ''
127
+ }
128
+
129
+ provide(selectKey, {
130
+ setSelected,
131
+ selection: selection,
132
+ })
133
+
134
+ const references = inject(referenceKey)
135
+ const field = props.field
136
+ const reference: ReferenceContext = {field, init, getCondition}
137
+ references?.value.push(reference)
138
+
139
+ defineExpose({
140
+ getCondition,
141
+ init,
142
+ })
143
+ </script>
@@ -0,0 +1,19 @@
1
+ import FuSearchInput from "./FuSearchInput.vue"
2
+ import FuFilterBar from "./FuFilterBar.vue";
3
+ import FuFilter from "./FuFilter.vue";
4
+ import FuFilterSelect from "./filter-components/FuFilterSelect.vue";
5
+ import FuFilterDate from "./filter-components/FuFilterDate.vue";
6
+ import FuFilterDateTime from "./filter-components/FuFilterDateTime.vue";
7
+
8
+ import type {App} from 'vue'
9
+
10
+ export default {
11
+ install: (app: App): void => {
12
+ app.component(FuFilterBar.name, FuFilterBar)
13
+ app.component(FuFilter.name, FuFilter)
14
+ app.component(FuSearchInput.name, FuSearchInput)
15
+ app.component(FuFilterSelect.name, FuFilterSelect)
16
+ app.component(FuFilterDate.name, FuFilterDate)
17
+ app.component(FuFilterDateTime.name, FuFilterDateTime)
18
+ }
19
+ }
@@ -0,0 +1,31 @@
1
+ import {InjectionKey, Ref} from "vue";
2
+
3
+ export const selectKey = Symbol('SelectKey') as unknown as InjectionKey<SelectContext>
4
+
5
+ export interface SelectContext {
6
+ selection: Ref<Array<string | number> | string | number>
7
+
8
+ setSelected(value: string | number, selected: boolean): void
9
+ }
10
+
11
+ export const referenceKey = Symbol('ReferenceKey') as unknown as InjectionKey<Ref<ReferenceContext[]>>
12
+
13
+ export interface ReferenceContext {
14
+ field: string,
15
+
16
+ init(v: any): void
17
+
18
+ getCondition(): FilterCondition | undefined
19
+ }
20
+
21
+ export interface OptionProps {
22
+ label: string
23
+ value: string | number
24
+ }
25
+
26
+ export interface FilterCondition {
27
+ field: string
28
+ label?: string
29
+ value: any
30
+ valueLabel?: string
31
+ }
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <fu-read-write-switch :write-trigger="writeTrigger" :data="data">
3
+ <template #default="{ read }">
4
+ <el-input v-model="data" v-bind="$attrs" @input="input" @blur="blur(read, $event)"
5
+ @keydown="keydown(read, $event)" />
6
+ </template>
7
+ </fu-read-write-switch>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+
12
+ import { ref, watch } from "vue";
13
+ defineOptions({ name: "FuInputRwSwitch" });
14
+ const props = defineProps({
15
+ value: [String, Number],
16
+ writeTrigger: {
17
+ type: String,
18
+ default: "click",
19
+ validator: (value: string) => {
20
+ return ['click', 'dblclick'].includes(value)
21
+ }
22
+ }
23
+ })
24
+ const emit = defineEmits(["input", "blur"])
25
+
26
+ const data = ref(props.value)
27
+
28
+ watch(() => props.value, (v) => {
29
+ data.value = v
30
+ })
31
+
32
+ function input(e: Event) {
33
+ emit("input", data.value, e)
34
+ }
35
+ function blur(read: Function, e: Event) {
36
+ emit("blur", data.value, e)
37
+ read()
38
+ }
39
+ function keydown(read: Function, e: KeyboardEvent) {
40
+ if (e.key === "Enter") {
41
+ read()
42
+ }
43
+ }
44
+ </script>
@@ -0,0 +1,91 @@
1
+ <script lang="ts">
2
+ import { ref, watch, defineComponent, h, nextTick } from 'vue'
3
+ import { uuid } from "@/tools/utils"
4
+
5
+ const TRIGGERS = ['manual', 'click', 'dblclick']
6
+
7
+ export default defineComponent({
8
+ name: "FuReadWriteSwitch",
9
+ props: {
10
+ value: Boolean,
11
+ data: [String, Number, Boolean],
12
+ writeTrigger: {
13
+ type: String,
14
+ default: "click",
15
+ validator: (value: string) => {
16
+ return TRIGGERS.includes(value)
17
+ }
18
+ }
19
+ },
20
+
21
+ setup(props, { slots, emit }) {
22
+ const id = ref(uuid())
23
+ const write = ref(props.value === undefined ? false : props.value)
24
+ watch(() => props.value, (v) => {
25
+ console.log(v)
26
+ if (v === write.value) return
27
+
28
+ if (v) {
29
+ switchWrite()
30
+ } else {
31
+ switchRead()
32
+ }
33
+ })
34
+
35
+ function change() {
36
+ emit("input", write.value)
37
+ emit("change", [props.data, write.value])
38
+ }
39
+ function switchWrite() {
40
+ write.value = true
41
+
42
+ nextTick(() => {
43
+ // 目前只支持input和textarea自动获取焦点
44
+ const nid = document.getElementById(id.value)
45
+ const input = nid?.querySelector("input")
46
+ input?.click() // el-select等组件自动展开
47
+ input?.focus()
48
+ const textarea = nid?.querySelector("textarea")
49
+ textarea?.focus()
50
+
51
+ // 可以在change事件自定义获取焦点
52
+ change()
53
+ })
54
+ }
55
+ function switchRead() {
56
+ write.value = false
57
+ change()
58
+ }
59
+
60
+ const context: any = {
61
+ class: "fu-read-write-switch",
62
+ attrs: { id: id.value },
63
+ on: {}
64
+ }
65
+
66
+ // 读状态添加触发写状态的事件
67
+ if (!write.value && props.writeTrigger !== TRIGGERS[0]) {
68
+ context.on[props.writeTrigger] = switchWrite
69
+ }
70
+ // 没有slot时显示文本数据
71
+ let children: any = props.data
72
+
73
+ // 读状态内容,提供切换到写状态的方法
74
+ if (!write.value && slots.read) {
75
+ children = slots.read({
76
+ write: switchWrite
77
+ })
78
+ }
79
+
80
+ // 写状态内容,提供切换到读状态的方法
81
+ if (write.value && slots.default) {
82
+ children = slots.default({
83
+ read: switchRead
84
+ })
85
+ }
86
+
87
+ return () => h("div", context, children)
88
+ }
89
+
90
+ })
91
+ </script>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <fu-read-write-switch :write-trigger="writeTrigger" :data="data">
3
+ <template #read>
4
+ <slot name="read">
5
+ {{ data }}
6
+ </slot>
7
+ </template>
8
+ <template #default="{ read }">
9
+ <el-select v-model="data" v-bind="$attrs" @input="input" @blur="blur(read, $event)"
10
+ @change="change(read, $event)">
11
+ <slot>
12
+ <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
13
+ </slot>
14
+ </el-select>
15
+ </template>
16
+ </fu-read-write-switch>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { ref, watch } from "vue";
21
+ defineOptions({ name: "FuSelectRwSwitch" });
22
+ const props = defineProps({
23
+ value: [String, Number],
24
+ options: Array,
25
+ writeTrigger: {
26
+ type: String,
27
+ default: "click",
28
+ validator: (value: string) => {
29
+ return ['click', 'dblclick'].includes(value)
30
+ }
31
+ }
32
+ })
33
+ const emit = defineEmits(["input", "blur", "change"])
34
+ const data = ref(props.value)
35
+
36
+ watch(() => props.value, (v) => {
37
+ data.value = v
38
+ })
39
+ function input(e: Event) {
40
+ emit("input", data.value, e)
41
+ }
42
+ function blur(read: Function, e: Event) {
43
+ setTimeout(() => {
44
+ read()
45
+ }, 100)
46
+ emit("blur", data.value, e)
47
+ }
48
+ function change(read: Function, e: Event) {
49
+ emit("change", data.value, e)
50
+ read()
51
+ }
52
+
53
+ </script>
@@ -0,0 +1,13 @@
1
+ import FuReadWriteSwitch from "./FuReadWriteSwitch.vue"
2
+ import FuInputRwSwitch from "./FuInputRwSwitch.vue"
3
+ import FuSelectRwSwitch from "./FuSelectRwSwitch.vue"
4
+
5
+ import type { App } from 'vue'
6
+
7
+ FuReadWriteSwitch.install = (app: App): void => {
8
+ app.component(FuReadWriteSwitch.name, FuReadWriteSwitch)
9
+ app.component(FuInputRwSwitch.name, FuInputRwSwitch)
10
+ app.component(FuSelectRwSwitch.name, FuSelectRwSwitch)
11
+ }
12
+
13
+ export default FuReadWriteSwitch;
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <div class="fu-complex-search">
3
+ <el-popover trigger="manual" v-model="active" :show-arrow="false" @hide="closePopover"
4
+ popper-class="fu-complex-components">
5
+
6
+ <div class="fu-complex-components__body">
7
+ <slot>
8
+ <!-- :size="configSize" -->
9
+ <component v-for="(c, i) in components" :key="i" :is="c.component" v-bind="c" :ref="c.field" v-on="c" />
10
+ </slot>
11
+ </div>
12
+ <div class="fu-complex-components__footer">
13
+ <!-- :size="configSize" -->
14
+ <el-button @click="active = false">{{ t('fu.search_bar.cancel') }}</el-button>
15
+ <el-button type="primary" @click="ok">{{ t('fu.search_bar.ok') }}</el-button>
16
+ </div>
17
+ <template #reference>
18
+ <!-- :size="configSize" -->
19
+ <fu-search-bar-button icon="ArrowRight" @click="toggle"
20
+ :class="['fu-complex-search__trigger', { 'is-active': active }]" :tooltip="t('fu.search_bar.adv_search')" />
21
+ </template>
22
+ </el-popover>
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { ref, computed, useSlots, getCurrentInstance } from "vue";
28
+ import FuSearchBarButton from "@/components/search-bar/FuSearchBarButton.vue";
29
+ import { useLocale } from "@/hooks"
30
+
31
+ const slots = useSlots()
32
+ const instance = getCurrentInstance()
33
+
34
+ const props = defineProps({
35
+ components: Array,
36
+ });
37
+ const emit = defineEmits(["close", "change"])
38
+ const { t } = useLocale()
39
+ const active = ref(false)
40
+
41
+
42
+ function closePopover() {
43
+ emit("close")
44
+ }
45
+ function toggle() {
46
+ active.value = !active.value
47
+ refs.value.forEach((r: any) => {
48
+ // *****r.init 有问题
49
+ if (r?.init) {
50
+ r.init()
51
+ } else {
52
+ console.warn("init undefined", r)
53
+ }
54
+ })
55
+ }
56
+
57
+ function close() {
58
+ active.value = false
59
+ }
60
+ function ok() {
61
+ active.value = false
62
+ let conditions: any = [];
63
+ refs.value.forEach((r: any) => {
64
+ let condition
65
+ if (r.getCondition) {
66
+ condition = r.getCondition()
67
+ } else {
68
+ console.warn("getCondition undefined", r)
69
+ }
70
+ if (condition && condition.value !== undefined) {
71
+ conditions.push(condition)
72
+ }
73
+ })
74
+ emit("change", conditions)
75
+ }
76
+
77
+ function createConditions(conditions: any) {
78
+ let result: any = []
79
+ if (conditions) {
80
+ Object.keys(conditions).forEach(key => {
81
+ let c = conditions[key]
82
+ refs.value.forEach((r: any) => {
83
+ if (r.field === key) {
84
+ result.push(r.createCondition(c.value, c.operator))
85
+ }
86
+ })
87
+ })
88
+ }
89
+ return result
90
+ }
91
+ const refs = computed(() => {
92
+ let refs: any = [];
93
+ if (slots.default?.()[0].children.length) {
94
+ // 使用slot
95
+ slots.default?.().forEach((component: any) => {
96
+ refs.push(component.componentInstance)
97
+ })
98
+ } else {
99
+ // 使用components
100
+ props.components.forEach((c: any) => {
101
+ refs.push(instance.refs[c.field][0])
102
+ })
103
+ }
104
+ return refs
105
+ });
106
+
107
+
108
+ </script>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <!-- , 'fu-quick-search--' + configSize -->
3
+ <div :class="['fu-quick-search']">
4
+ <el-icon v-if="useIcon">
5
+ <Search />
6
+ </el-icon>
7
+ <label>
8
+ <input :placeholder="placeholder" v-model="quick" @input="input" @blur="blur" @keydown="keydown" />
9
+ </label>
10
+ </div>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { ref, watch } from "vue";
15
+ defineOptions({ name: "FuQuickSearch" });
16
+ const props = defineProps({
17
+ value: String,
18
+ placeholder: String,
19
+ useIcon: {
20
+ type: Boolean,
21
+ default: true
22
+ }
23
+ })
24
+
25
+ const emit = defineEmits(["input", "change"])
26
+ const quick = ref("")
27
+
28
+ watch(() => props.value, (val: any) => {
29
+ quick.value = val
30
+ })
31
+ function input(e: Event) {
32
+ emit("input", quick.value, e)
33
+ }
34
+ function blur(e: Event) {
35
+ emit("change", quick.value, e)
36
+ }
37
+ function keydown(e: Event) {
38
+ const event = e as KeyboardEvent
39
+ if (event.key === "Enter") {
40
+ emit("change", quick.value, e)
41
+ }
42
+ }
43
+ </script>