DefaultForm.vue 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280
  1. <script setup lang="tsx">
  2. import { Form } from '@/components/Form'
  3. import { reactive, ref, onMounted, computed, unref } from 'vue'
  4. import { useI18n } from '@/hooks/web/useI18n'
  5. import { useIcon } from '@/hooks/web/useIcon'
  6. import { ContentWrap } from '@/components/ContentWrap'
  7. import { useAppStore } from '@/store/modules/app'
  8. import { FormSchema } from '@/types/form'
  9. import { ComponentOptions } from '@/types/components'
  10. import { useForm } from '@/hooks/web/useForm'
  11. const appStore = useAppStore()
  12. const { t } = useI18n()
  13. const isMobile = computed(() => appStore.getMobile)
  14. const toggle = ref(false)
  15. const restaurants = ref<Recordable[]>([])
  16. const querySearch = (queryString: string, cb: Fn) => {
  17. const results = queryString
  18. ? restaurants.value.filter(createFilter(queryString))
  19. : restaurants.value
  20. // call callback function to return suggestions
  21. cb(results)
  22. }
  23. let timeout: NodeJS.Timeout
  24. const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
  25. const results = queryString
  26. ? restaurants.value.filter(createFilter(queryString))
  27. : restaurants.value
  28. clearTimeout(timeout)
  29. timeout = setTimeout(() => {
  30. cb(results)
  31. }, 3000 * Math.random())
  32. }
  33. const createFilter = (queryString: string) => {
  34. return (restaurant: Recordable) => {
  35. return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
  36. }
  37. }
  38. const loadAll = () => {
  39. return [
  40. { value: 'vue', link: 'https://github.com/vuejs/vue' },
  41. { value: 'element', link: 'https://github.com/ElemeFE/element' },
  42. { value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
  43. { value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
  44. { value: 'vuex', link: 'https://github.com/vuejs/vuex' },
  45. { value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
  46. { value: 'babel', link: 'https://github.com/babel/babel' }
  47. ]
  48. }
  49. const handleSelect = (item: Recordable) => {
  50. console.log(item)
  51. }
  52. onMounted(() => {
  53. restaurants.value = loadAll()
  54. })
  55. const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  56. const options = ref<ComponentOptions[]>(
  57. Array.from({ length: 1000 }).map((_, idx) => ({
  58. value: `Option ${idx + 1}`,
  59. label: `${initials[idx % 10]}${idx}`
  60. }))
  61. )
  62. const options2 = ref<ComponentOptions[]>(
  63. Array.from({ length: 10 }).map((_, idx) => {
  64. const label = idx + 1
  65. return {
  66. value: `Group ${label}`,
  67. label: `Group ${label}`,
  68. options: Array.from({ length: 10 }).map((_, idx) => ({
  69. value: `Option ${idx + 1 + 10 * label}`,
  70. label: `${initials[idx % 10]}${idx + 1 + 10 * label}`
  71. }))
  72. }
  73. })
  74. )
  75. const options3: ComponentOptions[] = [
  76. {
  77. value: 'guide',
  78. label: 'Guide',
  79. children: [
  80. {
  81. value: 'disciplines',
  82. label: 'Disciplines',
  83. children: [
  84. {
  85. value: 'consistency',
  86. label: 'Consistency'
  87. },
  88. {
  89. value: 'feedback',
  90. label: 'Feedback'
  91. },
  92. {
  93. value: 'efficiency',
  94. label: 'Efficiency'
  95. },
  96. {
  97. value: 'controllability',
  98. label: 'Controllability'
  99. }
  100. ]
  101. },
  102. {
  103. value: 'navigation',
  104. label: 'Navigation',
  105. children: [
  106. {
  107. value: 'side nav',
  108. label: 'Side Navigation'
  109. },
  110. {
  111. value: 'top nav',
  112. label: 'Top Navigation'
  113. }
  114. ]
  115. }
  116. ]
  117. },
  118. {
  119. value: 'component',
  120. label: 'Component',
  121. children: [
  122. {
  123. value: 'basic',
  124. label: 'Basic',
  125. children: [
  126. {
  127. value: 'layout',
  128. label: 'Layout'
  129. },
  130. {
  131. value: 'color',
  132. label: 'Color'
  133. },
  134. {
  135. value: 'typography',
  136. label: 'Typography'
  137. },
  138. {
  139. value: 'icon',
  140. label: 'Icon'
  141. },
  142. {
  143. value: 'button',
  144. label: 'Button'
  145. }
  146. ]
  147. },
  148. {
  149. value: 'form',
  150. label: 'Form',
  151. children: [
  152. {
  153. value: 'radio',
  154. label: 'Radio'
  155. },
  156. {
  157. value: 'checkbox',
  158. label: 'Checkbox'
  159. },
  160. {
  161. value: 'input',
  162. label: 'Input'
  163. },
  164. {
  165. value: 'input-number',
  166. label: 'InputNumber'
  167. },
  168. {
  169. value: 'select',
  170. label: 'Select'
  171. },
  172. {
  173. value: 'cascader',
  174. label: 'Cascader'
  175. },
  176. {
  177. value: 'switch',
  178. label: 'Switch'
  179. },
  180. {
  181. value: 'slider',
  182. label: 'Slider'
  183. },
  184. {
  185. value: 'time-picker',
  186. label: 'TimePicker'
  187. },
  188. {
  189. value: 'date-picker',
  190. label: 'DatePicker'
  191. },
  192. {
  193. value: 'datetime-picker',
  194. label: 'DateTimePicker'
  195. },
  196. {
  197. value: 'upload',
  198. label: 'Upload'
  199. },
  200. {
  201. value: 'rate',
  202. label: 'Rate'
  203. },
  204. {
  205. value: 'form',
  206. label: 'Form'
  207. }
  208. ]
  209. },
  210. {
  211. value: 'data',
  212. label: 'Data',
  213. children: [
  214. {
  215. value: 'table',
  216. label: 'Table'
  217. },
  218. {
  219. value: 'tag',
  220. label: 'Tag'
  221. },
  222. {
  223. value: 'progress',
  224. label: 'Progress'
  225. },
  226. {
  227. value: 'tree',
  228. label: 'Tree'
  229. },
  230. {
  231. value: 'pagination',
  232. label: 'Pagination'
  233. },
  234. {
  235. value: 'badge',
  236. label: 'Badge'
  237. }
  238. ]
  239. },
  240. {
  241. value: 'notice',
  242. label: 'Notice',
  243. children: [
  244. {
  245. value: 'alert',
  246. label: 'Alert'
  247. },
  248. {
  249. value: 'loading',
  250. label: 'Loading'
  251. },
  252. {
  253. value: 'message',
  254. label: 'Message'
  255. },
  256. {
  257. value: 'message-box',
  258. label: 'MessageBox'
  259. },
  260. {
  261. value: 'notification',
  262. label: 'Notification'
  263. }
  264. ]
  265. },
  266. {
  267. value: 'navigation',
  268. label: 'Navigation',
  269. children: [
  270. {
  271. value: 'menu',
  272. label: 'Menu'
  273. },
  274. {
  275. value: 'tabs',
  276. label: 'Tabs'
  277. },
  278. {
  279. value: 'breadcrumb',
  280. label: 'Breadcrumb'
  281. },
  282. {
  283. value: 'dropdown',
  284. label: 'Dropdown'
  285. },
  286. {
  287. value: 'steps',
  288. label: 'Steps'
  289. }
  290. ]
  291. },
  292. {
  293. value: 'others',
  294. label: 'Others',
  295. children: [
  296. {
  297. value: 'dialog',
  298. label: 'Dialog'
  299. },
  300. {
  301. value: 'tooltip',
  302. label: 'Tooltip'
  303. },
  304. {
  305. value: 'popover',
  306. label: 'Popover'
  307. },
  308. {
  309. value: 'card',
  310. label: 'Card'
  311. },
  312. {
  313. value: 'carousel',
  314. label: 'Carousel'
  315. },
  316. {
  317. value: 'collapse',
  318. label: 'Collapse'
  319. }
  320. ]
  321. }
  322. ]
  323. }
  324. ]
  325. const generateData = () => {
  326. const data: {
  327. value: number
  328. desc: string
  329. disabled: boolean
  330. }[] = []
  331. for (let i = 1; i <= 15; i++) {
  332. data.push({
  333. value: i,
  334. desc: `Option ${i}`,
  335. disabled: i % 4 === 0
  336. })
  337. }
  338. return data
  339. }
  340. const holidays = [
  341. '2021-10-01',
  342. '2021-10-02',
  343. '2021-10-03',
  344. '2021-10-04',
  345. '2021-10-05',
  346. '2021-10-06',
  347. '2021-10-07'
  348. ]
  349. const isHoliday = ({ dayjs }) => {
  350. return holidays.includes(dayjs.format('YYYY-MM-DD'))
  351. }
  352. const schema = reactive<FormSchema[]>([
  353. {
  354. field: 'field1',
  355. label: t('formDemo.input'),
  356. component: 'Divider'
  357. },
  358. {
  359. field: 'field2',
  360. label: t('formDemo.default'),
  361. component: 'Input',
  362. componentProps: {
  363. formatter: (value) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
  364. parser: (value) => value.replace(/\$\s?|(,*)/g, '')
  365. }
  366. },
  367. {
  368. field: 'field3',
  369. label: `${t('formDemo.icon')}1`,
  370. component: 'Input',
  371. componentProps: {
  372. suffixIcon: useIcon({ icon: 'ep:calendar' }),
  373. prefixIcon: () => {
  374. return unref(toggle) ? useIcon({ icon: 'ep:calendar' }) : useIcon({ icon: 'ep:share' })
  375. }
  376. }
  377. },
  378. {
  379. field: 'field4',
  380. label: `${t('formDemo.icon')}2`,
  381. component: 'Input',
  382. componentProps: {
  383. slots: {
  384. suffix: (_, data: any) => {
  385. return unref(toggle) && data.field4
  386. ? useIcon({ icon: 'ep:calendar' })
  387. : useIcon({ icon: 'ep:share' })
  388. },
  389. prefix: useIcon({ icon: 'ep:calendar' })
  390. }
  391. }
  392. },
  393. {
  394. field: 'field5',
  395. label: t('formDemo.mixed'),
  396. component: 'Input',
  397. componentProps: {
  398. slots: {
  399. prepend: useIcon({ icon: 'ep:calendar' }),
  400. append: (_, data: any) => {
  401. return data.field5 ? useIcon({ icon: 'ep:calendar' }) : useIcon({ icon: 'ep:share' })
  402. }
  403. }
  404. }
  405. },
  406. {
  407. field: 'input-field7',
  408. label: t('formDemo.password'),
  409. component: 'Input',
  410. componentProps: {
  411. showPassword: true
  412. }
  413. },
  414. {
  415. field: 'field6',
  416. label: t('formDemo.textarea'),
  417. component: 'Input',
  418. componentProps: {
  419. type: 'textarea',
  420. rows: 2
  421. }
  422. },
  423. {
  424. field: 'field7',
  425. label: t('formDemo.autocomplete'),
  426. component: 'Divider'
  427. },
  428. {
  429. field: 'field8',
  430. label: t('formDemo.default'),
  431. component: 'Autocomplete',
  432. componentProps: {
  433. fetchSuggestions: querySearch,
  434. on: {
  435. select: handleSelect
  436. }
  437. }
  438. },
  439. {
  440. field: 'field9',
  441. label: t('formDemo.slot'),
  442. component: 'Autocomplete',
  443. componentProps: {
  444. fetchSuggestions: querySearch,
  445. on: {
  446. select: handleSelect
  447. },
  448. slots: {
  449. default: (item: any) => {
  450. return (
  451. <>
  452. <div class="value">{item.value}</div>
  453. <span class="link">{item.link}</span>
  454. </>
  455. )
  456. }
  457. }
  458. }
  459. },
  460. {
  461. field: 'autocomplete-field10',
  462. label: t('formDemo.remoteSearch'),
  463. component: 'Autocomplete',
  464. componentProps: {
  465. fetchSuggestions: querySearchAsync,
  466. on: {
  467. select: handleSelect
  468. }
  469. }
  470. },
  471. {
  472. field: 'field10',
  473. component: 'Divider',
  474. label: t('formDemo.inputNumber')
  475. },
  476. {
  477. field: 'field11',
  478. label: t('formDemo.default'),
  479. component: 'InputNumber',
  480. value: 0
  481. },
  482. {
  483. field: 'field12',
  484. label: t('formDemo.position'),
  485. component: 'InputNumber',
  486. componentProps: {
  487. controlsPosition: 'right'
  488. },
  489. value: 10
  490. },
  491. {
  492. field: 'field13',
  493. label: t('formDemo.select'),
  494. component: 'Divider'
  495. },
  496. {
  497. field: 'field14',
  498. label: t('formDemo.default'),
  499. component: 'Select',
  500. componentProps: {
  501. optionDisabled: (item: any, data: any) => {
  502. console.log(item, data)
  503. return false
  504. },
  505. options: [
  506. {
  507. disabled: true,
  508. label: 'option1',
  509. value: '1'
  510. },
  511. {
  512. label: 'option2',
  513. value: '2'
  514. }
  515. ]
  516. }
  517. },
  518. {
  519. field: 'field15',
  520. label: t('formDemo.slot'),
  521. component: 'Select',
  522. componentProps: {
  523. options: [
  524. {
  525. label: 'option1',
  526. value: '1'
  527. },
  528. {
  529. label: 'option2',
  530. value: '2'
  531. }
  532. ],
  533. slots: {
  534. default: (item) => {
  535. console.log(item)
  536. return (
  537. <>
  538. <span style="float: left">{item.label}</span>
  539. <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px;">
  540. {item.value}
  541. </span>
  542. </>
  543. )
  544. }
  545. }
  546. }
  547. }
  548. // {
  549. // field: 'field16',
  550. // label: t('formDemo.selectGroup'),
  551. // component: 'Select',
  552. // componentProps: {
  553. // options: [
  554. // {
  555. // label: 'option1',
  556. // options: [
  557. // {
  558. // disabled: true,
  559. // label: 'option1-1',
  560. // value: '1-1'
  561. // },
  562. // {
  563. // label: 'option1-2',
  564. // value: '1-2'
  565. // }
  566. // ]
  567. // },
  568. // {
  569. // label: 'option2',
  570. // options: [
  571. // {
  572. // label: 'option2-1',
  573. // value: '2-1'
  574. // },
  575. // {
  576. // label: 'option2-2',
  577. // value: '2-2'
  578. // }
  579. // ]
  580. // }
  581. // ]
  582. // }
  583. // },
  584. // {
  585. // field: 'field17',
  586. // label: `${t('formDemo.selectGroup')}${t('formDemo.slot')}`,
  587. // component: 'Select',
  588. // componentProps: {
  589. // options: [
  590. // {
  591. // label: 'option1',
  592. // options: [
  593. // {
  594. // label: 'option1-1',
  595. // value: '1-1',
  596. // disabled: true
  597. // },
  598. // {
  599. // label: 'option1-2',
  600. // value: '1-2'
  601. // }
  602. // ]
  603. // },
  604. // {
  605. // label: 'option2',
  606. // options: [
  607. // {
  608. // label: 'option2-1',
  609. // value: '2-1'
  610. // },
  611. // {
  612. // label: 'option2-2',
  613. // value: '2-2'
  614. // }
  615. // ]
  616. // }
  617. // ],
  618. // optionsSlot: true
  619. // }
  620. // },
  621. // {
  622. // field: 'field18',
  623. // label: `${t('formDemo.selectV2')}`,
  624. // component: 'Divider'
  625. // },
  626. // {
  627. // field: 'field19',
  628. // label: t('formDemo.default'),
  629. // component: 'SelectV2',
  630. // componentProps: {
  631. // options: options.value
  632. // }
  633. // },
  634. // {
  635. // field: 'field20',
  636. // label: t('formDemo.slot'),
  637. // component: 'SelectV2',
  638. // componentProps: {
  639. // options: options.value,
  640. // slots: {
  641. // default: true
  642. // }
  643. // }
  644. // },
  645. // {
  646. // field: 'field21',
  647. // label: t('formDemo.selectGroup'),
  648. // component: 'SelectV2',
  649. // componentProps: {
  650. // options: options2.value
  651. // }
  652. // },
  653. // {
  654. // field: 'field22',
  655. // label: `${t('formDemo.selectGroup')}${t('formDemo.slot')}`,
  656. // component: 'SelectV2',
  657. // componentProps: {
  658. // options: options2.value,
  659. // slots: {
  660. // default: true
  661. // }
  662. // }
  663. // },
  664. // {
  665. // field: 'field23',
  666. // label: t('formDemo.cascader'),
  667. // component: 'Divider'
  668. // },
  669. // {
  670. // field: 'field24',
  671. // label: t('formDemo.default'),
  672. // component: 'Cascader',
  673. // componentProps: {
  674. // options: options3
  675. // }
  676. // },
  677. // {
  678. // field: 'field25',
  679. // label: t('formDemo.slot'),
  680. // component: 'Cascader',
  681. // componentProps: {
  682. // options: options3,
  683. // slots: {
  684. // default: true
  685. // }
  686. // }
  687. // },
  688. // {
  689. // field: 'field26',
  690. // label: t('formDemo.switch'),
  691. // component: 'Divider'
  692. // },
  693. // {
  694. // field: 'field27',
  695. // label: t('formDemo.default'),
  696. // component: 'Switch',
  697. // value: false
  698. // },
  699. // {
  700. // field: 'field28',
  701. // label: t('formDemo.icon'),
  702. // component: 'Switch',
  703. // value: false,
  704. // componentProps: {
  705. // activeIcon: useIcon({ icon: 'ep:check' }),
  706. // inactiveIcon: useIcon({ icon: 'ep:close' })
  707. // }
  708. // },
  709. // {
  710. // field: 'field29',
  711. // label: t('formDemo.rate'),
  712. // component: 'Divider'
  713. // },
  714. // {
  715. // field: 'field30',
  716. // label: t('formDemo.default'),
  717. // component: 'Rate',
  718. // value: null
  719. // },
  720. // {
  721. // field: 'field31',
  722. // label: t('formDemo.icon'),
  723. // component: 'Rate',
  724. // value: null,
  725. // componentProps: {
  726. // voidIcon: useIcon({ icon: 'ep:chat-round' }),
  727. // icons: [
  728. // useIcon({ icon: 'ep:chat-round' }),
  729. // useIcon({ icon: 'ep:chat-line-round' }),
  730. // useIcon({ icon: 'ep:chat-dot-round' })
  731. // ]
  732. // }
  733. // },
  734. // {
  735. // field: 'field32',
  736. // label: t('formDemo.colorPicker'),
  737. // component: 'Divider'
  738. // },
  739. // {
  740. // field: 'field33',
  741. // label: t('formDemo.default'),
  742. // component: 'ColorPicker'
  743. // },
  744. // {
  745. // field: 'field34',
  746. // label: t('formDemo.transfer'),
  747. // component: 'Divider'
  748. // },
  749. // {
  750. // field: 'field35',
  751. // label: t('formDemo.default'),
  752. // component: 'Transfer',
  753. // componentProps: {
  754. // props: {
  755. // key: 'value',
  756. // label: 'desc',
  757. // disabled: 'disabled'
  758. // },
  759. // data: generateData()
  760. // },
  761. // value: [],
  762. // colProps: {
  763. // span: 24
  764. // }
  765. // },
  766. // {
  767. // field: 'field36',
  768. // label: t('formDemo.slot'),
  769. // component: 'Transfer',
  770. // componentProps: {
  771. // props: {
  772. // key: 'value',
  773. // label: 'desc',
  774. // disabled: 'disabled'
  775. // },
  776. // leftDefaultChecked: [2, 3],
  777. // rightDefaultChecked: [1],
  778. // data: generateData(),
  779. // slots: {
  780. // default: true
  781. // }
  782. // },
  783. // value: [1],
  784. // colProps: {
  785. // span: 24
  786. // }
  787. // },
  788. // {
  789. // field: 'field37',
  790. // label: `${t('formDemo.render')}`,
  791. // component: 'Transfer',
  792. // componentProps: {
  793. // props: {
  794. // key: 'value',
  795. // label: 'desc',
  796. // disabled: 'disabled'
  797. // },
  798. // leftDefaultChecked: [2, 3],
  799. // rightDefaultChecked: [1],
  800. // data: generateData(),
  801. // renderContent: (h: Fn, option: Recordable) => {
  802. // return h('span', null, `${option.value} - ${option.desc}`)
  803. // }
  804. // },
  805. // value: [1],
  806. // colProps: {
  807. // span: 24
  808. // }
  809. // },
  810. // {
  811. // field: 'field38',
  812. // label: t('formDemo.radio'),
  813. // component: 'Divider'
  814. // },
  815. // {
  816. // field: 'field39',
  817. // label: t('formDemo.default'),
  818. // component: 'Radio',
  819. // componentProps: {
  820. // options: [
  821. // {
  822. // disabled: true,
  823. // label: 'option-1',
  824. // value: '1'
  825. // },
  826. // {
  827. // label: 'option-2',
  828. // value: '2'
  829. // }
  830. // ]
  831. // }
  832. // },
  833. // {
  834. // field: 'field40',
  835. // label: t('formDemo.button'),
  836. // component: 'RadioButton',
  837. // componentProps: {
  838. // options: [
  839. // {
  840. // disabled: true,
  841. // label: 'option-1',
  842. // value: '1'
  843. // },
  844. // {
  845. // label: 'option-2',
  846. // value: '2'
  847. // }
  848. // ]
  849. // }
  850. // },
  851. // {
  852. // field: 'field41',
  853. // label: t('formDemo.checkbox'),
  854. // component: 'Divider'
  855. // },
  856. // {
  857. // field: 'field42',
  858. // label: t('formDemo.default'),
  859. // component: 'Checkbox',
  860. // value: [],
  861. // componentProps: {
  862. // options: [
  863. // {
  864. // disabled: true,
  865. // label: 'option-1',
  866. // value: '1'
  867. // },
  868. // {
  869. // label: 'option-2',
  870. // value: '2'
  871. // },
  872. // {
  873. // label: 'option-3',
  874. // value: '23'
  875. // }
  876. // ]
  877. // }
  878. // },
  879. // {
  880. // field: 'field43',
  881. // label: t('formDemo.button'),
  882. // component: 'CheckboxButton',
  883. // value: [],
  884. // componentProps: {
  885. // options: [
  886. // {
  887. // disabled: true,
  888. // label: 'option-1',
  889. // value: '1'
  890. // },
  891. // {
  892. // label: 'option-2',
  893. // value: '2'
  894. // },
  895. // {
  896. // label: 'option-3',
  897. // value: '23'
  898. // }
  899. // ]
  900. // }
  901. // },
  902. // {
  903. // field: 'field44',
  904. // component: 'Divider',
  905. // label: t('formDemo.slider')
  906. // },
  907. // {
  908. // field: 'field45',
  909. // component: 'Slider',
  910. // label: t('formDemo.default'),
  911. // value: 0
  912. // },
  913. // {
  914. // field: 'field46',
  915. // component: 'Divider',
  916. // label: t('formDemo.datePicker')
  917. // },
  918. // {
  919. // field: 'field47',
  920. // component: 'DatePicker',
  921. // label: t('formDemo.default'),
  922. // componentProps: {
  923. // type: 'date'
  924. // }
  925. // },
  926. // {
  927. // field: 'field48',
  928. // component: 'DatePicker',
  929. // label: t('formDemo.shortcuts'),
  930. // componentProps: {
  931. // type: 'date',
  932. // disabledDate: (time: Date) => {
  933. // return time.getTime() > Date.now()
  934. // },
  935. // shortcuts: [
  936. // {
  937. // text: t('formDemo.today'),
  938. // value: new Date()
  939. // },
  940. // {
  941. // text: t('formDemo.yesterday'),
  942. // value: () => {
  943. // const date = new Date()
  944. // date.setTime(date.getTime() - 3600 * 1000 * 24)
  945. // return date
  946. // }
  947. // },
  948. // {
  949. // text: t('formDemo.aWeekAgo'),
  950. // value: () => {
  951. // const date = new Date()
  952. // date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
  953. // return date
  954. // }
  955. // }
  956. // ]
  957. // }
  958. // },
  959. // {
  960. // field: 'field49',
  961. // component: 'DatePicker',
  962. // label: t('formDemo.week'),
  963. // componentProps: {
  964. // type: 'week',
  965. // format: `[${t('formDemo.week')}] ww`
  966. // }
  967. // },
  968. // {
  969. // field: 'field50',
  970. // component: 'DatePicker',
  971. // label: t('formDemo.year'),
  972. // componentProps: {
  973. // type: 'year'
  974. // }
  975. // },
  976. // {
  977. // field: 'field51',
  978. // component: 'DatePicker',
  979. // label: t('formDemo.month'),
  980. // componentProps: {
  981. // type: 'month'
  982. // }
  983. // },
  984. // {
  985. // field: 'field52',
  986. // component: 'DatePicker',
  987. // label: t('formDemo.dates'),
  988. // componentProps: {
  989. // type: 'dates'
  990. // }
  991. // },
  992. // {
  993. // field: 'field53',
  994. // component: 'DatePicker',
  995. // label: t('formDemo.daterange'),
  996. // componentProps: {
  997. // type: 'daterange'
  998. // }
  999. // },
  1000. // {
  1001. // field: 'field54',
  1002. // component: 'DatePicker',
  1003. // label: t('formDemo.monthrange'),
  1004. // componentProps: {
  1005. // type: 'monthrange'
  1006. // }
  1007. // },
  1008. // {
  1009. // field: 'field55',
  1010. // component: 'DatePicker',
  1011. // label: t('formDemo.slot'),
  1012. // componentProps: {
  1013. // type: 'date',
  1014. // format: 'YYYY/MM/DD',
  1015. // valueFormat: 'YYYY-MM-DD',
  1016. // slots: {
  1017. // default: true
  1018. // }
  1019. // }
  1020. // },
  1021. // {
  1022. // field: 'field56',
  1023. // component: 'Divider',
  1024. // label: t('formDemo.dateTimePicker')
  1025. // },
  1026. // {
  1027. // field: 'field57',
  1028. // component: 'DatePicker',
  1029. // label: t('formDemo.default'),
  1030. // componentProps: {
  1031. // type: 'datetime'
  1032. // }
  1033. // },
  1034. // {
  1035. // field: 'field58',
  1036. // component: 'DatePicker',
  1037. // label: t('formDemo.shortcuts'),
  1038. // componentProps: {
  1039. // type: 'datetime',
  1040. // shortcuts: [
  1041. // {
  1042. // text: t('formDemo.today'),
  1043. // value: new Date()
  1044. // },
  1045. // {
  1046. // text: t('formDemo.yesterday'),
  1047. // value: () => {
  1048. // const date = new Date()
  1049. // date.setTime(date.getTime() - 3600 * 1000 * 24)
  1050. // return date
  1051. // }
  1052. // },
  1053. // {
  1054. // text: t('formDemo.aWeekAgo'),
  1055. // value: () => {
  1056. // const date = new Date()
  1057. // date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
  1058. // return date
  1059. // }
  1060. // }
  1061. // ]
  1062. // }
  1063. // },
  1064. // {
  1065. // field: 'field59',
  1066. // component: 'DatePicker',
  1067. // label: t('formDemo.dateTimerange'),
  1068. // componentProps: {
  1069. // type: 'datetimerange'
  1070. // }
  1071. // },
  1072. // {
  1073. // field: 'field60',
  1074. // component: 'Divider',
  1075. // label: t('formDemo.timePicker')
  1076. // },
  1077. // {
  1078. // field: 'field61',
  1079. // component: 'TimePicker',
  1080. // label: t('formDemo.default')
  1081. // },
  1082. // {
  1083. // field: 'field62',
  1084. // component: 'Divider',
  1085. // label: t('formDemo.timeSelect')
  1086. // },
  1087. // {
  1088. // field: 'field63',
  1089. // component: 'TimeSelect',
  1090. // label: t('formDemo.default')
  1091. // }
  1092. ])
  1093. const { register, formRef, methods } = useForm({
  1094. schema,
  1095. labelWidth: 'auto',
  1096. labelPosition: isMobile.value ? 'top' : 'right'
  1097. })
  1098. const changeToggle = () => {
  1099. toggle.value = !unref(toggle)
  1100. }
  1101. </script>
  1102. <template>
  1103. <button @click="changeToggle">测试</button>
  1104. <ContentWrap :title="t('formDemo.defaultForm')" :message="t('formDemo.formDes')">
  1105. <!-- <Form :schema="schema" label-width="auto" :label-position="isMobile ? 'top' : 'right'">
  1106. <template #field4-prefix>
  1107. <Icon icon="ep:calendar" class="el-input__icon" />
  1108. </template>
  1109. <template #field4-suffix>
  1110. <Icon icon="ep:calendar" class="el-input__icon" />
  1111. </template>
  1112. <template #field5-prepend> Http:// </template>
  1113. <template #field5-append> .com </template>
  1114. <template #field9-default="{ item }">
  1115. <div class="value">{{ item.value }}</div>
  1116. <span class="link">{{ item.link }}</span>
  1117. </template>
  1118. <template #field15-option="{ item }">
  1119. <span style="float: left">{{ item.label }}</span>
  1120. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1121. {{ item.value }}
  1122. </span>
  1123. </template>
  1124. <template #field17-option="{ item }">
  1125. <span style="float: left">{{ item.label }}</span>
  1126. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1127. {{ item.value }}
  1128. </span>
  1129. </template>
  1130. <template #field20-default="{ item }">
  1131. <span style="float: left">{{ item.label }}</span>
  1132. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1133. {{ item.value }}
  1134. </span>
  1135. </template>
  1136. <template #field22-default="{ item }">
  1137. <span style="float: left">{{ item.label }}</span>
  1138. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1139. {{ item.value }}
  1140. </span>
  1141. </template>
  1142. <template #field25-default="{ node, data }">
  1143. <span>{{ data.label }}</span>
  1144. <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
  1145. </template>
  1146. <template #field36-default="{ option }">
  1147. <span>{{ option.value }} - {{ option.desc }}</span>
  1148. </template>
  1149. <template #field55-default="cell">
  1150. <div class="cell" :class="{ current: cell.isCurrent }">
  1151. <span class="text">{{ cell.text }}</span>
  1152. <span v-if="isHoliday(cell)" class="holiday"></span>
  1153. </div>
  1154. </template>
  1155. </Form> -->
  1156. <Form @register="register">
  1157. <!-- <template #field4-prefix>
  1158. <Icon icon="ep:calendar" class="el-input__icon" />
  1159. </template>
  1160. <template #field4-suffix>
  1161. <Icon icon="ep:calendar" class="el-input__icon" />
  1162. </template>
  1163. <template #field5-prepend> Http:// </template>
  1164. <template #field5-append> .com </template>
  1165. <template #field9-default="{ item }">
  1166. <div class="value">{{ item.value }}</div>
  1167. <span class="link">{{ item.link }}</span>
  1168. </template>
  1169. <template #field15-option="{ item }">
  1170. <span style="float: left">{{ item.label }}</span>
  1171. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1172. {{ item.value }}
  1173. </span>
  1174. </template>
  1175. <template #field17-option="{ item }">
  1176. <span style="float: left">{{ item.label }}</span>
  1177. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1178. {{ item.value }}
  1179. </span>
  1180. </template>
  1181. <template #field20-default="{ item }">
  1182. <span style="float: left">{{ item.label }}</span>
  1183. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1184. {{ item.value }}
  1185. </span>
  1186. </template>
  1187. <template #field22-default="{ item }">
  1188. <span style="float: left">{{ item.label }}</span>
  1189. <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
  1190. {{ item.value }}
  1191. </span>
  1192. </template>
  1193. <template #field25-default="{ node, data }">
  1194. <span>{{ data.label }}</span>
  1195. <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
  1196. </template>
  1197. <template #field36-default="{ option }">
  1198. <span>{{ option.value }} - {{ option.desc }}</span>
  1199. </template>
  1200. <template #field55-default="cell">
  1201. <div class="cell" :class="{ current: cell.isCurrent }">
  1202. <span class="text">{{ cell.text }}</span>
  1203. <span v-if="isHoliday(cell)" class="holiday"></span>
  1204. </div>
  1205. </template> -->
  1206. </Form>
  1207. </ContentWrap>
  1208. </template>
  1209. <style lang="less" scoped>
  1210. .cell {
  1211. height: 30px;
  1212. padding: 3px 0;
  1213. box-sizing: border-box;
  1214. .text {
  1215. position: absolute;
  1216. left: 50%;
  1217. display: block;
  1218. width: 24px;
  1219. height: 24px;
  1220. margin: 0 auto;
  1221. line-height: 24px;
  1222. border-radius: 50%;
  1223. transform: translateX(-50%);
  1224. }
  1225. &.current {
  1226. .text {
  1227. color: #fff;
  1228. background: purple;
  1229. }
  1230. }
  1231. .holiday {
  1232. position: absolute;
  1233. bottom: 0px;
  1234. left: 50%;
  1235. width: 6px;
  1236. height: 6px;
  1237. background: red;
  1238. border-radius: 50%;
  1239. transform: translateX(-50%);
  1240. }
  1241. }
  1242. </style>