basic.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <script lang="ts" setup>
  2. import { Page } from '@vben/common-ui';
  3. import { Button, Card, message } from 'ant-design-vue';
  4. import dayjs from 'dayjs';
  5. import { useVbenForm } from '#/adapter/form';
  6. import DocButton from '../doc-button.vue';
  7. const [BaseForm, baseFormApi] = useVbenForm({
  8. // 所有表单项共用,可单独在表单内覆盖
  9. commonConfig: {
  10. // 所有表单项
  11. componentProps: {
  12. class: 'w-full',
  13. },
  14. },
  15. // 提交函数
  16. handleSubmit: onSubmit,
  17. // 垂直布局,label和input在不同行,值为vertical
  18. // 水平布局,label和input在同一行
  19. layout: 'horizontal',
  20. schema: [
  21. {
  22. // 组件需要在 #/adapter.ts内注册,并加上类型
  23. component: 'Input',
  24. // 对应组件的参数
  25. componentProps: {
  26. placeholder: '请输入用户名',
  27. },
  28. // 字段名
  29. fieldName: 'username',
  30. // 界面显示的label
  31. label: '字符串',
  32. },
  33. {
  34. component: 'InputPassword',
  35. componentProps: {
  36. placeholder: '请输入密码',
  37. },
  38. fieldName: 'password',
  39. label: '密码',
  40. },
  41. {
  42. component: 'InputNumber',
  43. componentProps: {
  44. placeholder: '请输入',
  45. },
  46. fieldName: 'number',
  47. label: '数字(带后缀)',
  48. suffix: () => '¥',
  49. },
  50. {
  51. component: 'Select',
  52. componentProps: {
  53. allowClear: true,
  54. filterOption: true,
  55. options: [
  56. {
  57. label: '选项1',
  58. value: '1',
  59. },
  60. {
  61. label: '选项2',
  62. value: '2',
  63. },
  64. ],
  65. placeholder: '请选择',
  66. showSearch: true,
  67. },
  68. fieldName: 'options',
  69. label: '下拉选',
  70. },
  71. {
  72. component: 'RadioGroup',
  73. componentProps: {
  74. options: [
  75. {
  76. label: '选项1',
  77. value: '1',
  78. },
  79. {
  80. label: '选项2',
  81. value: '2',
  82. },
  83. ],
  84. },
  85. fieldName: 'radioGroup',
  86. label: '单选组',
  87. },
  88. {
  89. component: 'Radio',
  90. fieldName: 'radio',
  91. label: '',
  92. renderComponentContent: () => {
  93. return {
  94. default: () => ['Radio'],
  95. };
  96. },
  97. },
  98. {
  99. component: 'CheckboxGroup',
  100. componentProps: {
  101. name: 'cname',
  102. options: [
  103. {
  104. label: '选项1',
  105. value: '1',
  106. },
  107. {
  108. label: '选项2',
  109. value: '2',
  110. },
  111. ],
  112. },
  113. fieldName: 'checkboxGroup',
  114. label: '多选组',
  115. },
  116. {
  117. component: 'Checkbox',
  118. fieldName: 'checkbox',
  119. label: '',
  120. renderComponentContent: () => {
  121. return {
  122. default: () => ['我已阅读并同意'],
  123. };
  124. },
  125. },
  126. {
  127. component: 'Mentions',
  128. componentProps: {
  129. options: [
  130. {
  131. label: 'afc163',
  132. value: 'afc163',
  133. },
  134. {
  135. label: 'zombieJ',
  136. value: 'zombieJ',
  137. },
  138. ],
  139. placeholder: '请输入',
  140. },
  141. fieldName: 'mentions',
  142. label: '提及',
  143. },
  144. {
  145. component: 'Rate',
  146. fieldName: 'rate',
  147. label: '评分',
  148. },
  149. {
  150. component: 'Switch',
  151. componentProps: {
  152. class: 'w-auto',
  153. },
  154. fieldName: 'switch',
  155. label: '开关',
  156. },
  157. {
  158. component: 'DatePicker',
  159. fieldName: 'datePicker',
  160. label: '日期选择框',
  161. },
  162. {
  163. component: 'RangePicker',
  164. fieldName: 'rangePicker',
  165. label: '范围选择器',
  166. },
  167. {
  168. component: 'TimePicker',
  169. fieldName: 'timePicker',
  170. label: '时间选择框',
  171. },
  172. {
  173. component: 'TreeSelect',
  174. componentProps: {
  175. allowClear: true,
  176. placeholder: '请选择',
  177. showSearch: true,
  178. treeData: [
  179. {
  180. label: 'root 1',
  181. value: 'root 1',
  182. children: [
  183. {
  184. label: 'parent 1',
  185. value: 'parent 1',
  186. children: [
  187. {
  188. label: 'parent 1-0',
  189. value: 'parent 1-0',
  190. children: [
  191. {
  192. label: 'my leaf',
  193. value: 'leaf1',
  194. },
  195. {
  196. label: 'your leaf',
  197. value: 'leaf2',
  198. },
  199. ],
  200. },
  201. {
  202. label: 'parent 1-1',
  203. value: 'parent 1-1',
  204. },
  205. ],
  206. },
  207. {
  208. label: 'parent 2',
  209. value: 'parent 2',
  210. },
  211. ],
  212. },
  213. ],
  214. treeNodeFilterProp: 'label',
  215. },
  216. fieldName: 'treeSelect',
  217. label: '树选择',
  218. },
  219. ],
  220. // 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
  221. wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
  222. });
  223. const [CustomLayoutForm] = useVbenForm({
  224. // 所有表单项共用,可单独在表单内覆盖
  225. commonConfig: {
  226. // 所有表单项
  227. componentProps: {
  228. class: 'w-full',
  229. },
  230. },
  231. layout: 'horizontal',
  232. schema: [
  233. {
  234. component: 'Select',
  235. fieldName: 'field1',
  236. label: '字符串',
  237. },
  238. {
  239. component: 'TreeSelect',
  240. fieldName: 'field2',
  241. label: '字符串',
  242. },
  243. {
  244. component: 'Mentions',
  245. fieldName: 'field3',
  246. label: '字符串',
  247. },
  248. {
  249. component: 'Input',
  250. fieldName: 'field4',
  251. label: '字符串',
  252. },
  253. {
  254. component: 'InputNumber',
  255. fieldName: 'field5',
  256. // 从第三列开始 相当于中间空了一列
  257. formItemClass: 'col-start-3',
  258. label: '前面空了一列',
  259. },
  260. {
  261. component: 'Textarea',
  262. fieldName: 'field6',
  263. // 占满三列空间 基线对齐
  264. formItemClass: 'col-span-3 items-baseline',
  265. label: '占满三列',
  266. },
  267. {
  268. component: 'Input',
  269. fieldName: 'field7',
  270. // 占满2列空间 从第二列开始 相当于前面空了一列
  271. formItemClass: 'col-span-2 col-start-2',
  272. label: '占满2列',
  273. },
  274. {
  275. component: 'Input',
  276. fieldName: 'field8',
  277. // 左右留空
  278. formItemClass: 'col-start-2',
  279. label: '左右留空',
  280. },
  281. {
  282. component: 'InputPassword',
  283. fieldName: 'field9',
  284. formItemClass: 'col-start-1',
  285. label: '字符串',
  286. },
  287. ],
  288. // 一共三列
  289. wrapperClass: 'grid-cols-3',
  290. });
  291. function onSubmit(values: Record<string, any>) {
  292. message.success({
  293. content: `form values: ${JSON.stringify(values)}`,
  294. });
  295. }
  296. function handleSetFormValue() {
  297. /**
  298. * 设置表单值(多个)
  299. */
  300. baseFormApi.setValues({
  301. checkboxGroup: ['1'],
  302. datePicker: dayjs('2022-01-01'),
  303. mentions: '@afc163',
  304. number: 3,
  305. options: '1',
  306. password: '2',
  307. radioGroup: '1',
  308. rangePicker: [dayjs('2022-01-01'), dayjs('2022-01-02')],
  309. rate: 3,
  310. switch: true,
  311. timePicker: dayjs('2022-01-01 12:00:00'),
  312. treeSelect: 'leaf1',
  313. username: '1',
  314. });
  315. // 设置单个表单值
  316. baseFormApi.setFieldValue('checkbox', true);
  317. }
  318. </script>
  319. <template>
  320. <Page
  321. content-class="flex flex-col gap-4"
  322. description="表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。"
  323. title="表单组件"
  324. >
  325. <template #extra>
  326. <DocButton path="/components/common-ui/vben-form" />
  327. </template>
  328. <Card title="基础示例">
  329. <template #extra>
  330. <Button type="primary" @click="handleSetFormValue">设置表单值</Button>
  331. </template>
  332. <BaseForm />
  333. </Card>
  334. <Card title="使用tailwind自定义布局">
  335. <CustomLayoutForm />
  336. </Card>
  337. </Page>
  338. </template>