jobsys-explore 1.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 (127) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc.cjs +38 -0
  3. package/.prettierrc.cjs +38 -0
  4. package/README.md +42 -0
  5. package/components/button/ExButton.jsx +119 -0
  6. package/components/button/index.js +4 -0
  7. package/components/button/index.less +8 -0
  8. package/components/form/ExAddress.jsx +125 -0
  9. package/components/form/ExCascader.jsx +98 -0
  10. package/components/form/ExCheckbox.jsx +59 -0
  11. package/components/form/ExDate.jsx +130 -0
  12. package/components/form/ExDatetime.jsx +152 -0
  13. package/components/form/ExField.jsx +123 -0
  14. package/components/form/ExFieldUploader.jsx +44 -0
  15. package/components/form/ExForm.jsx +395 -0
  16. package/components/form/ExNumber.jsx +49 -0
  17. package/components/form/ExRadio.jsx +58 -0
  18. package/components/form/ExRate.jsx +47 -0
  19. package/components/form/ExSelect.jsx +151 -0
  20. package/components/form/ExSlider.jsx +53 -0
  21. package/components/form/ExSwitch.jsx +49 -0
  22. package/components/form/ExTime.jsx +104 -0
  23. package/components/form/FormItem.jsx +229 -0
  24. package/components/form/PickerWrapper.jsx +111 -0
  25. package/components/form/addressData.json +1 -0
  26. package/components/form/index.js +37 -0
  27. package/components/form/index.less +108 -0
  28. package/components/form/utils.js +47 -0
  29. package/components/grid/ExGrid.jsx +53 -0
  30. package/components/grid/index.js +4 -0
  31. package/components/grid/index.less +3 -0
  32. package/components/index.js +9 -0
  33. package/components/pagination/ExPagination.jsx +148 -0
  34. package/components/pagination/index.js +5 -0
  35. package/components/pagination/index.less +15 -0
  36. package/components/provider/ExProvider.jsx +91 -0
  37. package/components/provider/index.js +4 -0
  38. package/components/qrcode/ExQrcode.jsx +86 -0
  39. package/components/qrcode/index.js +5 -0
  40. package/components/qrcode/index.less +8 -0
  41. package/components/result/ExResult.jsx +122 -0
  42. package/components/result/index.js +5 -0
  43. package/components/result/index.less +60 -0
  44. package/components/search/ExSearch.jsx +252 -0
  45. package/components/search/components/Expand.jsx +77 -0
  46. package/components/search/components/Field.jsx +27 -0
  47. package/components/search/components/Quick.jsx +53 -0
  48. package/components/search/components/index.js +5 -0
  49. package/components/search/index.js +5 -0
  50. package/components/search/index.less +119 -0
  51. package/components/search/utils.js +30 -0
  52. package/components/theme/ExTheme.jsx +10 -0
  53. package/components/theme/index.js +4 -0
  54. package/components/theme/index.less +97 -0
  55. package/components/uploader/ExUploader.jsx +248 -0
  56. package/components/uploader/index.js +5 -0
  57. package/components/utils.js +150 -0
  58. package/dist/__vite-browser-external-2447137e.mjs +5 -0
  59. package/dist/__vite-browser-external-2447137e.mjs.map +1 -0
  60. package/dist/__vite-browser-external-b3701507.js +2 -0
  61. package/dist/__vite-browser-external-b3701507.js.map +1 -0
  62. package/dist/hooks.cjs +2 -0
  63. package/dist/hooks.cjs.map +1 -0
  64. package/dist/hooks.js +35 -0
  65. package/dist/hooks.js.map +1 -0
  66. package/dist/index-82d74e5f.mjs +2120 -0
  67. package/dist/index-82d74e5f.mjs.map +1 -0
  68. package/dist/index-b8729555.js +2 -0
  69. package/dist/index-b8729555.js.map +1 -0
  70. package/dist/jobsys-explore.cjs +9 -0
  71. package/dist/jobsys-explore.cjs.map +1 -0
  72. package/dist/jobsys-explore.js +18673 -0
  73. package/dist/jobsys-explore.js.map +1 -0
  74. package/dist/style.css +1 -0
  75. package/docgen.config.cjs +9 -0
  76. package/docs/.vitepress/cache/deps/_metadata.json +19 -0
  77. package/docs/.vitepress/cache/deps/package.json +3 -0
  78. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +162 -0
  79. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  80. package/docs/.vitepress/cache/deps/vue.js +10795 -0
  81. package/docs/.vitepress/cache/deps/vue.js.map +7 -0
  82. package/docs/.vitepress/config.mjs +43 -0
  83. package/docs/.vitepress/dist/404.html +19 -0
  84. package/docs/.vitepress/dist/assets/app.e0eb4814.js +1 -0
  85. package/docs/.vitepress/dist/assets/chunks/framework.7a64ad8e.js +2 -0
  86. package/docs/.vitepress/dist/assets/chunks/theme.ffc5f35c.js +7 -0
  87. package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.33bd5a8e.woff2 +0 -0
  88. package/docs/.vitepress/dist/assets/inter-italic-cyrillic.ea42a392.woff2 +0 -0
  89. package/docs/.vitepress/dist/assets/inter-italic-greek-ext.4fbe9427.woff2 +0 -0
  90. package/docs/.vitepress/dist/assets/inter-italic-greek.8f4463c4.woff2 +0 -0
  91. package/docs/.vitepress/dist/assets/inter-italic-latin-ext.bd8920cc.woff2 +0 -0
  92. package/docs/.vitepress/dist/assets/inter-italic-latin.bd3b6f56.woff2 +0 -0
  93. package/docs/.vitepress/dist/assets/inter-italic-vietnamese.6ce511fb.woff2 +0 -0
  94. package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.e75737ce.woff2 +0 -0
  95. package/docs/.vitepress/dist/assets/inter-roman-cyrillic.5f2c6c8c.woff2 +0 -0
  96. package/docs/.vitepress/dist/assets/inter-roman-greek-ext.ab0619bc.woff2 +0 -0
  97. package/docs/.vitepress/dist/assets/inter-roman-greek.d5a6d92a.woff2 +0 -0
  98. package/docs/.vitepress/dist/assets/inter-roman-latin-ext.0030eebd.woff2 +0 -0
  99. package/docs/.vitepress/dist/assets/inter-roman-latin.2ed14f66.woff2 +0 -0
  100. package/docs/.vitepress/dist/assets/inter-roman-vietnamese.14ce25a6.woff2 +0 -0
  101. package/docs/.vitepress/dist/assets/style.6747f984.css +1 -0
  102. package/docs/.vitepress/dist/hashmap.json +1 -0
  103. package/docs/.vitepress/theme/index.css +0 -0
  104. package/docs/.vitepress/theme/index.js +12 -0
  105. package/hooks/cipher.js +40 -0
  106. package/hooks/form.js +176 -0
  107. package/hooks/index.js +4 -0
  108. package/hooks/network.js +153 -0
  109. package/hooks/utils.js +61 -0
  110. package/index.html +17 -0
  111. package/index.js +10 -0
  112. package/package.json +75 -0
  113. package/playground/App.vue +45 -0
  114. package/playground/TestButton.vue +15 -0
  115. package/playground/TestForm.vue +271 -0
  116. package/playground/TestFormItem.vue +110 -0
  117. package/playground/TestGrid.vue +22 -0
  118. package/playground/TestPagination.vue +89 -0
  119. package/playground/TestQrcode.vue +7 -0
  120. package/playground/TestResult.vue +12 -0
  121. package/playground/TestSearch.vue +84 -0
  122. package/playground/http.js +23 -0
  123. package/playground/main.js +12 -0
  124. package/postcss.config.cjs +8 -0
  125. package/utils/style.js +13 -0
  126. package/utils/withInstall.js +7 -0
  127. package/vite.config.js +52 -0
@@ -0,0 +1,122 @@
1
+ import { defineComponent } from "vue"
2
+ import "./index.less"
3
+
4
+ /**
5
+ * ExResult 结果页
6
+ */
7
+ export default defineComponent({
8
+ name: "ExResult",
9
+ props: {
10
+ /**
11
+ * 结果类型
12
+ * @values 'success', 'error', 'info', 'warning'
13
+ */
14
+ type: { type: String, default: "success" },
15
+
16
+ /**
17
+ * 标题
18
+ */
19
+ title: { type: String, default: "" },
20
+
21
+ /**
22
+ * 描述
23
+ */
24
+ description: { type: String, default: "" },
25
+ },
26
+ setup(props, { slots }) {
27
+ const iconElem = () => {
28
+ let elem = null
29
+
30
+ if (slots.icon) {
31
+ elem = slots.icon()
32
+ } else {
33
+ switch (props.type) {
34
+ case "success":
35
+ elem = (
36
+ <i class={"exicon"}>
37
+ <svg
38
+ viewBox="64 64 896 896"
39
+ data-icon="check-circle"
40
+ width="1em"
41
+ height="1em"
42
+ fill="currentColor"
43
+ aria-hidden="true"
44
+ focusable="false"
45
+ >
46
+ <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path>
47
+ </svg>
48
+ </i>
49
+ )
50
+ break
51
+
52
+ case "info":
53
+ elem = (
54
+ <i class={"exicon"}>
55
+ <svg
56
+ viewBox="64 64 896 896"
57
+ data-icon="exclamation-circle"
58
+ width="1em"
59
+ height="1em"
60
+ fill="currentColor"
61
+ aria-hidden="true"
62
+ focusable="false"
63
+ >
64
+ <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z"></path>
65
+ </svg>
66
+ </i>
67
+ )
68
+ break
69
+
70
+ case "warning":
71
+ elem = (
72
+ <i class={"exicon"}>
73
+ <svg
74
+ viewBox="64 64 896 896"
75
+ data-icon="warning"
76
+ width="1em"
77
+ height="1em"
78
+ fill="currentColor"
79
+ aria-hidden="true"
80
+ focusable="false"
81
+ >
82
+ <path d="M955.7 856l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zM480 416c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v184c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V416zm32 352a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z"></path>
83
+ </svg>
84
+ </i>
85
+ )
86
+ break
87
+
88
+ case "error":
89
+ elem = (
90
+ <i class={"exicon"}>
91
+ <svg
92
+ viewBox="64 64 896 896"
93
+ data-icon="close-circle"
94
+ width="1em"
95
+ height="1em"
96
+ fill="currentColor"
97
+ aria-hidden="true"
98
+ focusable="false"
99
+ >
100
+ <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path>
101
+ </svg>
102
+ </i>
103
+ )
104
+ break
105
+ default:
106
+ break
107
+ }
108
+ }
109
+
110
+ return elem
111
+ }
112
+
113
+ return () => (
114
+ <div class={`ex-result ex-result__${props.type}`}>
115
+ <div class={"ex-result-icon"}>{iconElem()}</div>
116
+ <div class={"ex-result-title"}>{slots.title ? slots.title?.() : props.title}</div>
117
+ <div class={"ex-result-description"}>{slots.description ? slots.description?.() : props.description}</div>
118
+ <div class={"ex-result-extra"}>{slots.extra?.()}</div>
119
+ </div>
120
+ )
121
+ },
122
+ })
@@ -0,0 +1,5 @@
1
+ import _ExResult from "./ExResult.jsx"
2
+ import withInstall from "../../utils/withInstall"
3
+
4
+ export const ExResult = withInstall(_ExResult)
5
+ export default ExResult
@@ -0,0 +1,60 @@
1
+ .ex-result {
2
+ padding: 48px 32px;
3
+
4
+ .ex-result-icon {
5
+ margin-bottom: 24px;
6
+ text-align: center;
7
+
8
+ & > .exicon {
9
+ font-size: 72px;
10
+ }
11
+ }
12
+
13
+ .ex-result-title {
14
+ color: rgba(0, 0, 0, .85);
15
+ font-size: 24px;
16
+ line-height: 1.8;
17
+ text-align: center;
18
+ }
19
+
20
+ .ex-result-description {
21
+ color: rgba(0, 0, 0, .45);
22
+ font-size: 14px;
23
+ line-height: 1.6;
24
+ text-align: center;
25
+ }
26
+
27
+ .ex-result-extra {
28
+ margin-top: 32px;
29
+ text-align: center;
30
+ }
31
+
32
+ &.ex-result__success .ex-result-icon > .exicon {
33
+ color: #52c41a;
34
+ }
35
+
36
+ &.ex-result__info .ex-result-icon > .exicon {
37
+ color: #1890ff;
38
+ }
39
+
40
+ &.ex-result__warning .ex-result-icon > .exicon {
41
+ color: #faad14;
42
+ }
43
+
44
+ &.ex-result__error .ex-result-icon > .exicon {
45
+ color: #f5222d;
46
+ }
47
+
48
+ .exicon {
49
+ display: inline-block;
50
+ color: inherit;
51
+ font-style: normal;
52
+ line-height: 0;
53
+ text-align: center;
54
+ text-transform: none;
55
+ vertical-align: -.125em;
56
+ text-rendering: optimizeLegibility;
57
+ -webkit-font-smoothing: antialiased;
58
+ -moz-osx-font-smoothing: grayscale;
59
+ }
60
+ }
@@ -0,0 +1,252 @@
1
+ import { defineComponent, reactive, ref } from "vue"
2
+ import { Button, Icon, Popup, Search } from "vant"
3
+ import { find, isArray, isFunction } from "lodash-es"
4
+ import { createExpand, createField, createQuick } from "./components"
5
+ import "./index.less"
6
+ import ExGrid from "../grid/ExGrid.jsx"
7
+
8
+ /**
9
+ * ExSearch 搜索组件
10
+ * @version 1.0.0
11
+ */
12
+ export default defineComponent({
13
+ name: "ExSearch",
14
+ props: {
15
+ modelValue: { type: String, default: "" },
16
+
17
+ /**
18
+ * @typedef {Object} ExSearchItemConfig 搜索项
19
+ * @property {string} key 搜索项的 key
20
+ * @property {string} title 搜索项的标题
21
+ * @property {string} type 搜索项的类型
22
+ * @property {boolean} [primary] 为 true 列表展示为搜索框,该项存在会覆盖 keyword 配置
23
+ * @property {boolean} [quick] 为 true 展示为快速检索项
24
+ * @property {boolean|Object} [expandable] 搜索项是否展开
25
+ * @property {Array|Function} [options] 搜索项的选项
26
+ * @property {Object} [inputProps] 搜索项的输入框属性
27
+ * @property {*} [defaultValue] 搜索项的值
28
+ * @property {*} [_temp] 搜索项的临时值[内部使用]
29
+ * */
30
+
31
+ /**
32
+ *
33
+ * 搜索项的配置, 详见 [ExSearchItemConfig](#exsearchitemconfig-配置)
34
+ *
35
+ */
36
+ columns: { type: Array, default: () => [] },
37
+
38
+ /**
39
+ * 占位提示文字
40
+ */
41
+ placeholder: { type: String, default: "请输入搜索关键词" },
42
+
43
+ /**
44
+ * 名称,作为提交表单时的标识符
45
+ */
46
+ keyword: { type: String, default: "keyword" },
47
+
48
+ /**
49
+ * 搜索框左侧文本
50
+ */
51
+ label: { type: String, default: "" },
52
+
53
+ /**
54
+ * 是否将输入框设为只读状态,只读状态下无法输入内容
55
+ */
56
+ readonly: { type: Boolean, default: false },
57
+
58
+ /**
59
+ * 是否禁用输入框
60
+ */
61
+ disabled: { type: Boolean, default: false },
62
+
63
+ /**
64
+ * 输入框内容对齐方式
65
+ * @values left, right, center
66
+ */
67
+ inputAlign: { type: String, default: "left" },
68
+
69
+ /**
70
+ * [原生配置](https://vant-contrib.gitee.io/vant/#/zh-CN/search)
71
+ */
72
+ searchProps: { type: Object, default: () => ({}) },
73
+ },
74
+ emits: ["update:modelValue", "search"],
75
+ setup(props, { emit }) {
76
+ const componentValue = ref(props.modelValue)
77
+
78
+ const state = reactive({
79
+ queryForm: {}, // 搜索表单
80
+ quickColumns: [], //快速检索项
81
+ fieldColumns: [], //表单搜索项
82
+
83
+ showFilterPopup: false,
84
+ })
85
+
86
+ const initQueryForm = () => {
87
+ const form = {}
88
+ props.columns.forEach((item) => {
89
+ let value = ""
90
+ //如果是展开显示的,那么默认值为空字符串
91
+ //如果展开为多选,那么默认值为 []
92
+ if (item.expandable === "multiple" || item.type === "cascade") {
93
+ value = []
94
+ }
95
+
96
+ if (item.defaultValue) {
97
+ value = isFunction(item.defaultValue) ? item.defaultValue() : item.defaultValue
98
+ }
99
+
100
+ if (item.quick && !find(state.quickColumns, { key: item.key })) {
101
+ state.quickColumns.push(item)
102
+ } else {
103
+ if (item.expandable) {
104
+ if (!item.options) {
105
+ console.error(`expandable 为 true 时,必须提供 options 属性`)
106
+ return
107
+ }
108
+ }
109
+
110
+ if (!find(state.fieldColumns, { key: item.key })) {
111
+ state.fieldColumns.push(item)
112
+ }
113
+ }
114
+ form[item.key] = value
115
+ })
116
+
117
+ state.queryForm = form
118
+ }
119
+
120
+ initQueryForm()
121
+
122
+ const onUpdateValue = (value) => {
123
+ emit("update:modelValue", value)
124
+ }
125
+
126
+ const getQueryForm = () => {
127
+ const form = {}
128
+ Object.keys(state.queryForm).forEach((key) => {
129
+ let value = state.queryForm[key]
130
+
131
+ if (value && (!isArray(value) || value.length)) {
132
+ form[key] = value
133
+ }
134
+ })
135
+
136
+ if (componentValue.value) {
137
+ form[props.keyword] = componentValue.value
138
+ }
139
+
140
+ return form
141
+ }
142
+
143
+ const onOpenFilter = () => {
144
+ state.showFilterPopup = true
145
+ }
146
+
147
+ const onCloseFilter = () => {
148
+ state.showFilterPopup = false
149
+ }
150
+
151
+ const onSearch = () => {
152
+ const form = getQueryForm()
153
+ emit("search", form)
154
+ }
155
+
156
+ const onFieldSearch = () => {
157
+ state.showFilterPopup = false
158
+ onSearch()
159
+ }
160
+
161
+ const onClearFields = () => {
162
+ state.fieldColumns.forEach((item) => {
163
+ state.queryForm[item.key] = ""
164
+ })
165
+ }
166
+
167
+ /******************* render *********************/
168
+
169
+ const quickElems = () => {
170
+ return state.quickColumns.map((item) => createQuick(item, state.queryForm, onSearch))
171
+ }
172
+
173
+ const popupHeaderElem = () => (
174
+ <div class={"ex-search-popup__header van-hairline--bottom"}>
175
+ <h2 class={"ex-search-popup__title"}>{props.title}</h2>
176
+ <span class={"ex-search-popup__closer"}>
177
+ <Icon
178
+ name={"cross"}
179
+ class={"van-badge__wrapper van-popup__close-icon van-popup__close-icon--top-right van-haptics-feedback"}
180
+ onClick={() => (state.showFilterPopup = false)}
181
+ ></Icon>
182
+ </span>
183
+ </div>
184
+ )
185
+
186
+ const fieldElems = () => (
187
+ <div class={"ex-search-popup__content"}>
188
+ {state.fieldColumns.map((item) => (item.expandable ? createExpand(item, state.queryForm) : createField(item, state.queryForm)))}
189
+ </div>
190
+ )
191
+
192
+ const popupFooterElem = () => (
193
+ <div class={"ex-search-popup__footer van-hairline--top"}>
194
+ <ExGrid>
195
+ {{
196
+ default: () => [
197
+ <Button type={"default"} size={"small"} round={true} onClick={onClearFields}>
198
+ 清除
199
+ </Button>,
200
+ <Button type={"primary"} size={"small"} round={true} onClick={onFieldSearch}>
201
+ 搜索
202
+ </Button>,
203
+ ],
204
+ }}
205
+ </ExGrid>
206
+ </div>
207
+ )
208
+
209
+ return () => (
210
+ <div class="ex-search">
211
+ <Search
212
+ v-model={componentValue.value}
213
+ name={props.keyword}
214
+ shape={"round"}
215
+ label={props.label}
216
+ inputAlign={props.inputAlign}
217
+ disabled={props.disabled}
218
+ readonly={props.readonly}
219
+ placeholder={props.placeholder}
220
+ onUpdate:modelValue={onUpdateValue}
221
+ onSearch={onSearch}
222
+ {...props.searchProps}
223
+ ></Search>
224
+
225
+ <div class={"ex-search__quick-bar"}>
226
+ <div class={"ex-search__quick-container"}>{quickElems()}</div>
227
+ {state.fieldColumns?.length ? (
228
+ <div class={"ex-search__filter"} onClick={onOpenFilter}>
229
+ 筛选<Icon name={"filter-o"}></Icon>
230
+ </div>
231
+ ) : null}
232
+ </div>
233
+
234
+ <Popup
235
+ v-model:show={state.showFilterPopup}
236
+ closeable={false}
237
+ position={"bottom"}
238
+ round={true}
239
+ teleport={"body"}
240
+ closeOnPopstate={true}
241
+ class={`ex-search-popup`}
242
+ safeAreaInsetBottom={true}
243
+ safeAreaInsetTop={true}
244
+ onClickOverlay={onCloseFilter}
245
+ onClickCloseIcon={onCloseFilter}
246
+ >
247
+ {{ default: () => [popupHeaderElem(), fieldElems(), popupFooterElem()] }}
248
+ </Popup>
249
+ </div>
250
+ )
251
+ },
252
+ })
@@ -0,0 +1,77 @@
1
+ import { isUndefined } from "lodash-es"
2
+ import { reactive } from "vue"
3
+ import { Button, Collapse, CollapseItem } from "vant"
4
+ import ExGrid from "../../grid/ExGrid.jsx"
5
+
6
+ const render = (item, queryForm) => {
7
+ if (isUndefined(item._temp)) {
8
+ item._temp = reactive({
9
+ activeNames: item.key,
10
+ })
11
+ }
12
+
13
+ const toggleChooseOption = (value) => {
14
+ if (item.expandable === "multiple") {
15
+ if (!queryForm[item.key] || !queryForm[item.key]?.length) {
16
+ queryForm[item.key] = [value]
17
+ } else {
18
+ const index = queryForm[item.key].indexOf(value)
19
+ if (index === -1) {
20
+ queryForm[item.key].push(value)
21
+ } else {
22
+ queryForm[item.key].splice(index, 1)
23
+ }
24
+ }
25
+ } else {
26
+ queryForm[item.key] = queryForm[item.key] === value ? "" : value
27
+ }
28
+ }
29
+
30
+ const isOptionActive = (value) => {
31
+ if (item.expandable === "multiple") {
32
+ return queryForm[item.key]?.includes(value)
33
+ } else {
34
+ return queryForm[item.key] === value
35
+ }
36
+ }
37
+
38
+ const optionElems = () => (
39
+ <ExGrid columns={3}>
40
+ {{
41
+ default: () =>
42
+ item.options.map((option) => (
43
+ <Button
44
+ class={`ex-search__expand-option`}
45
+ type={`${isOptionActive(option.value) ? "primary" : "default"}`}
46
+ hairline={true}
47
+ round={true}
48
+ size={"small"}
49
+ onClick={() => toggleChooseOption(option.value)}
50
+ >
51
+ {option.text}
52
+ </Button>
53
+ )),
54
+ }}
55
+ </ExGrid>
56
+ )
57
+
58
+ return (
59
+ <div class={"ex-search__popup-item ex-search__expand-item"}>
60
+ <Collapse v-model={item._temp.activeNames} border={false} accordion={true}>
61
+ {{
62
+ default: () => (
63
+ <CollapseItem name={item.key}>
64
+ {{
65
+ default: () => <div class={"ex-search__expand-options"}>{optionElems()}</div>,
66
+ title: () => <span class={"ex-search__expand-title"}>{item.title}</span>,
67
+ value: () => <span class={"ex-search__expand-trigger"}>展开</span>,
68
+ }}
69
+ </CollapseItem>
70
+ ),
71
+ }}
72
+ </Collapse>
73
+ </div>
74
+ )
75
+ }
76
+
77
+ export default render
@@ -0,0 +1,27 @@
1
+ import ExSelect from "../../form/ExSelect.jsx"
2
+ import ExDate from "../../form/ExDate.jsx"
3
+ import ExDatetime from "../../form/ExDatetime.jsx"
4
+ import ExField from "../../form/ExField.jsx"
5
+ import ExNumber from "../../form/ExNumber.jsx"
6
+
7
+ const render = (item, queryForm) => {
8
+ const fieldElem = () => {
9
+ const fieldProps = { label: item.title, name: item.key, placeholder: `搜索${item.title}` }
10
+
11
+ if (item.type === "select") {
12
+ return <ExSelect v-model={queryForm[item.key]} clearable={true} options={item.options} {...fieldProps} {...item.inputProps}></ExSelect>
13
+ } else if (item.type === "date") {
14
+ return <ExDate v-model={queryForm[item.key]} {...fieldProps} {...item.inputProps}></ExDate>
15
+ } else if (item.type === "datetime") {
16
+ return <ExDatetime v-model={queryForm[item.key]} {...fieldProps} {...item.inputProps}></ExDatetime>
17
+ } else if (item.type === "number") {
18
+ return <ExNumber v-model={queryForm[item.key]} {...fieldProps} {...item.props}></ExNumber>
19
+ }
20
+
21
+ return <ExField v-model={queryForm[item.key]} {...fieldProps} {...item.inputProps}></ExField>
22
+ }
23
+
24
+ return <div class={"ex-search__popup-item ex-search__field-item"}>{fieldElem()}</div>
25
+ }
26
+
27
+ export default render
@@ -0,0 +1,53 @@
1
+ import { ref } from "vue"
2
+ import ExSelect from "../../form/ExSelect.jsx"
3
+ import ExCascader from "../../form/ExCascader.jsx"
4
+ import { Icon } from "vant"
5
+
6
+ const render = (item, queryForm, onSearch) => {
7
+ const selectRef = ref()
8
+ const cascadeRef = ref()
9
+
10
+ let renderItem
11
+ if (item.type === "select") {
12
+ renderItem = (
13
+ <ExSelect ref={selectRef} v-model={queryForm[item.key]} options={item.options} clearable={true} onChange={onSearch}>
14
+ {{
15
+ default: () => (
16
+ <div class={`ex-search__quick-trigger ${queryForm[item.key] ? "active" : ""}`}>
17
+ <span class={"ex-search__quick-label"}>{selectRef.value?.displayText || item.title}</span>
18
+ <span class={"ex-search__quick-icon"}>
19
+ <Icon name={"arrow-down"}></Icon>
20
+ </span>
21
+ </div>
22
+ ),
23
+ }}
24
+ </ExSelect>
25
+ )
26
+ } else if (item.type === "cascade") {
27
+ renderItem = (
28
+ <ExCascader
29
+ ref={cascadeRef}
30
+ v-model={queryForm[item.key]}
31
+ options={item.options}
32
+ clearable={true}
33
+ title={`搜索${item.title}`}
34
+ onChange={onSearch}
35
+ >
36
+ {{
37
+ default: () => (
38
+ <div class={`ex-search__quick-trigger ${queryForm[item.key]?.length ? "active" : ""}`}>
39
+ <span class={"ex-search__quick-label"}>{cascadeRef.value?.displayText || item.title}</span>
40
+ <span class={"ex-search__quick-icon"}>
41
+ <Icon name={"arrow-down"}></Icon>
42
+ </span>
43
+ </div>
44
+ ),
45
+ }}
46
+ </ExCascader>
47
+ )
48
+ }
49
+
50
+ return <div class={"ex-search__quick-item"}>{renderItem}</div>
51
+ }
52
+
53
+ export default render
@@ -0,0 +1,5 @@
1
+ import createExpand from "./Expand.jsx"
2
+ import createQuick from "./Quick.jsx"
3
+ import createField from "./Field.jsx"
4
+
5
+ export { createExpand, createQuick, createField }
@@ -0,0 +1,5 @@
1
+ import _ExSearch from "./ExSearch.jsx"
2
+ import withInstall from "../../utils/withInstall"
3
+
4
+ export const ExSearch = withInstall(_ExSearch)
5
+ export default ExSearch