basic.vue 8.5 KB

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