jobsys-explore 1.0.4 → 1.0.6

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.
package/README.md CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  # TODOs
3
2
 
4
3
  ---
@@ -6,32 +5,31 @@
6
5
  ## 增强
7
6
 
8
7
  - [ ] ExploreForm
9
- - [ ] Address
10
- - [ ] Cascader
11
- - [ ] Checkbox
12
- - [ ] Date
13
- - [ ] Group
14
- - [ ] Html
15
- - [ ] Input
16
- - [ ] Number
17
- - [ ] Radio
18
- - [ ] Remote
19
- - [ ] Select
20
- - [ ] Switch
21
- - [ ] Tag
22
- - [ ] Text
23
- - [ ] Time
24
- - [ ] TreeSelect
25
- - [ ] Uploader
26
-
27
- - [ ] ExploreSearch
28
- - [ ] 同上
29
-
30
-
31
- - [ ] Field
32
- - [ ] Disabled
33
- - [ ] Help
34
-
8
+ - [X] Address
9
+ - [X] Cascader
10
+ - [X] Checkbox
11
+ - [X] Date
12
+ - [ ] Group
13
+ - [ ] Html
14
+ - [X] Input
15
+ - [X] Number
16
+ - [X] Radio
17
+ - [ ] Remote
18
+ - [X] Select
19
+ - [X] Switch
20
+ - [] Tag
21
+ - [X] Text
22
+ - [X] Time
23
+ - [ ] TreeSelect
24
+ - [X] Uploader
25
+
26
+ - [X] ExploreSearch
27
+ - [X] 同上
28
+
29
+
30
+ - [X] Field
31
+ - [X] Disabled
32
+ - [X] Help
35
33
 
36
34
  ## 新增
37
35
 
@@ -92,7 +92,7 @@ export default defineComponent({
92
92
  fieldSlots.label = labelElem
93
93
  }
94
94
 
95
- if (fieldSlots.input) {
95
+ if (!fieldSlots.input) {
96
96
  fieldSlots.input = inputElem
97
97
  }
98
98
 
@@ -38,12 +38,14 @@ const render = (item, submitForm, { props, slots }) => {
38
38
  const pickerTypes = ["select", "date", "datetime", "time", "address", "cascade"]
39
39
  const isPicker = pickerTypes.includes(item.type)
40
40
 
41
+ // ExField 的 props
41
42
  const fieldProps = pick(item, ["placeholder", "help", "required", "disabled", "rules", "readonly", "isLink", "fieldProps"])
42
43
  fieldProps.label = item.title
43
44
  fieldProps.name = item.key
44
45
  fieldProps.placeholder = fieldProps.placeholder || (isPicker ? `请选择${item.title}` : `请填写${item.title}`)
45
46
  fieldProps.rules = fieldProps.rules || []
46
47
 
48
+ // 具体组件的 props
47
49
  let componentProps = pick(item, ["options"])
48
50
  if (item.defaultProps) {
49
51
  componentProps = { ...componentProps, ...item.defaultProps }
@@ -1,9 +1,10 @@
1
- export * from "./button"
2
- export * from "./theme"
3
- export * from "./form"
4
- export * from "./provider"
5
- export * from "./result"
6
- export * from "./qrcode"
7
- export * from "./pagination"
8
- export * from "./search"
9
- export * from "./uploader"
1
+ export * from "./button"
2
+ export * from "./theme"
3
+ export * from "./form"
4
+ export * from "./provider"
5
+ export * from "./result"
6
+ export * from "./qrcode"
7
+ export * from "./pagination"
8
+ export * from "./search"
9
+ export * from "./uploader"
10
+ export * from "./grid"
@@ -1,252 +1,253 @@
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
- })
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} [quick] 为 true 展示为快速检索项
23
+ * @property {boolean|Object} [expandable] 搜索项是否展开
24
+ * @property {Array|Function} [options] 搜索项的选项
25
+ * @property {Object} [inputProps] 搜索项的输入框属性
26
+ * @property {*} [defaultValue] 搜索项的值
27
+ * @property {*} [_temp] 搜索项的临时值[内部使用]
28
+ * */
29
+
30
+ /**
31
+ *
32
+ * 搜索项的配置, 详见 [ExSearchItemConfig](#exsearchitemconfig-配置)
33
+ *
34
+ */
35
+ columns: { type: Array, default: () => [] },
36
+
37
+ /**
38
+ * 占位提示文字
39
+ */
40
+ placeholder: { type: String, default: "请输入搜索关键词" },
41
+
42
+ /**
43
+ * 名称,作为提交表单时的标识符
44
+ */
45
+ keyword: { type: String, default: "keyword" },
46
+
47
+ /**
48
+ * 搜索框左侧文本
49
+ */
50
+ label: { type: String, default: "" },
51
+
52
+ /**
53
+ * 是否将输入框设为只读状态,只读状态下无法输入内容
54
+ */
55
+ readonly: { type: Boolean, default: false },
56
+
57
+ /**
58
+ * 是否禁用输入框
59
+ */
60
+ disabled: { type: Boolean, default: false },
61
+
62
+ /**
63
+ * 输入框内容对齐方式
64
+ * @values left, right, center
65
+ */
66
+ inputAlign: { type: String, default: "left" },
67
+
68
+ /**
69
+ * [原生配置](https://vant-contrib.gitee.io/vant/#/zh-CN/search)
70
+ */
71
+ searchProps: { type: Object, default: () => ({}) },
72
+ },
73
+ emits: ["update:modelValue", "search"],
74
+ setup(props, { emit }) {
75
+ const componentValue = ref(props.modelValue)
76
+
77
+ const state = reactive({
78
+ queryForm: {}, // 搜索表单
79
+ quickColumns: [], //快速检索项
80
+ fieldColumns: [], //表单搜索项
81
+
82
+ showFilterPopup: false,
83
+ })
84
+
85
+ const initQueryForm = () => {
86
+ const form = {}
87
+ props.columns.forEach((item) => {
88
+ let value = ""
89
+ //如果是展开显示的,那么默认值为空字符串
90
+ //如果展开为多选,那么默认值为 []
91
+ if (item.expandable === "multiple" || item.type === "cascade") {
92
+ value = []
93
+ }
94
+
95
+ if (item.defaultValue) {
96
+ value = isFunction(item.defaultValue) ? item.defaultValue() : item.defaultValue
97
+ }
98
+
99
+ if (item.quick && !find(state.quickColumns, { key: item.key })) {
100
+ state.quickColumns.push(item)
101
+ } else {
102
+ if (item.expandable) {
103
+ if (!item.options) {
104
+ console.error(`expandable 为 true 时,必须提供 options 属性`)
105
+ return
106
+ }
107
+ }
108
+
109
+ if (!find(state.fieldColumns, { key: item.key })) {
110
+ state.fieldColumns.push(item)
111
+ }
112
+ }
113
+ form[item.key] = value
114
+ })
115
+
116
+ state.queryForm = form
117
+ }
118
+
119
+ initQueryForm()
120
+
121
+ const onUpdateValue = (value) => {
122
+ emit("update:modelValue", value)
123
+ }
124
+
125
+ const getQueryForm = () => {
126
+ const form = {}
127
+ Object.keys(state.queryForm).forEach((key) => {
128
+ let value = state.queryForm[key]
129
+
130
+ if (value && (!isArray(value) || value.length)) {
131
+ form[key] = value
132
+ }
133
+ })
134
+
135
+ if (componentValue.value) {
136
+ form[props.keyword] = componentValue.value
137
+ }
138
+
139
+ return form
140
+ }
141
+
142
+ const onOpenFilter = () => {
143
+ state.showFilterPopup = true
144
+ }
145
+
146
+ const onCloseFilter = () => {
147
+ state.showFilterPopup = false
148
+ }
149
+
150
+ const onSearch = () => {
151
+ const form = getQueryForm()
152
+ emit("search", form)
153
+ }
154
+
155
+ const onFieldSearch = () => {
156
+ state.showFilterPopup = false
157
+ onSearch()
158
+ }
159
+
160
+ const onClearFields = () => {
161
+ state.fieldColumns.forEach((item) => {
162
+ state.queryForm[item.key] = ""
163
+ })
164
+ }
165
+
166
+ /******************* render *********************/
167
+
168
+ const quickElems = () => {
169
+ return state.quickColumns.map((item) => createQuick(item, state.queryForm, onSearch))
170
+ }
171
+
172
+ const popupHeaderElem = () => (
173
+ <div class={"ex-search-popup__header van-hairline--bottom"}>
174
+ <h2 class={"ex-search-popup__title"}>{props.title}</h2>
175
+ <span class={"ex-search-popup__closer"}>
176
+ <Icon
177
+ name={"cross"}
178
+ class={"van-badge__wrapper van-popup__close-icon van-popup__close-icon--top-right van-haptics-feedback"}
179
+ onClick={() => (state.showFilterPopup = false)}
180
+ ></Icon>
181
+ </span>
182
+ </div>
183
+ )
184
+
185
+ const fieldElems = () => (
186
+ <div class={"ex-search-popup__content"}>
187
+ {state.fieldColumns.map((item) => (item.expandable ? createExpand(item, state.queryForm) : createField(item, state.queryForm)))}
188
+ </div>
189
+ )
190
+
191
+ const popupFooterElem = () => (
192
+ <div class={"ex-search-popup__footer van-hairline--top"}>
193
+ <ExGrid>
194
+ {{
195
+ default: () => [
196
+ <Button type={"default"} size={"small"} round={true} onClick={onClearFields}>
197
+ 清除
198
+ </Button>,
199
+ <Button type={"primary"} size={"small"} round={true} onClick={onFieldSearch}>
200
+ 搜索
201
+ </Button>,
202
+ ],
203
+ }}
204
+ </ExGrid>
205
+ </div>
206
+ )
207
+
208
+ return () => (
209
+ <div class="ex-search">
210
+ <form action="/">
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
+ </form>
225
+
226
+ <div class={"ex-search__quick-bar"}>
227
+ <div class={"ex-search__quick-container"}>{quickElems()}</div>
228
+ {state.fieldColumns?.length ? (
229
+ <div class={"ex-search__filter"} onClick={onOpenFilter}>
230
+ 筛选<Icon name={"filter-o"}></Icon>
231
+ </div>
232
+ ) : null}
233
+ </div>
234
+
235
+ <Popup
236
+ v-model:show={state.showFilterPopup}
237
+ closeable={false}
238
+ position={"bottom"}
239
+ round={true}
240
+ teleport={"body"}
241
+ closeOnPopstate={true}
242
+ class={`ex-search-popup`}
243
+ safeAreaInsetBottom={true}
244
+ safeAreaInsetTop={true}
245
+ onClickOverlay={onCloseFilter}
246
+ onClickCloseIcon={onCloseFilter}
247
+ >
248
+ {{ default: () => [popupHeaderElem(), fieldElems(), popupFooterElem()] }}
249
+ </Popup>
250
+ </div>
251
+ )
252
+ },
253
+ })