dynamic.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <script lang="ts" setup>
  2. import { Page } from '@vben/common-ui';
  3. import { Button, Card, message } from 'ant-design-vue';
  4. import { useVbenForm } from '#/adapter';
  5. const [Form, formApi] = useVbenForm({
  6. // 提交函数
  7. handleSubmit: onSubmit,
  8. schema: [
  9. {
  10. component: 'Input',
  11. defaultValue: 'hidden value',
  12. dependencies: {
  13. show: false,
  14. // 随意一个字段改变时,都会触发
  15. triggerFields: ['field1Switch'],
  16. },
  17. fieldName: 'hiddenField',
  18. label: '隐藏字段',
  19. },
  20. {
  21. component: 'Switch',
  22. defaultValue: true,
  23. fieldName: 'field1Switch',
  24. help: '通过Dom控制销毁',
  25. label: '显示字段1',
  26. },
  27. {
  28. component: 'Switch',
  29. defaultValue: true,
  30. fieldName: 'field2Switch',
  31. help: '通过css控制隐藏',
  32. label: '显示字段2',
  33. },
  34. {
  35. component: 'Switch',
  36. fieldName: 'field3Switch',
  37. label: '禁用字段3',
  38. },
  39. {
  40. component: 'Switch',
  41. fieldName: 'field4Switch',
  42. label: '字段4必填',
  43. },
  44. {
  45. component: 'Input',
  46. dependencies: {
  47. if(values) {
  48. return !!values.field1Switch;
  49. },
  50. // 只有指定的字段改变时,才会触发
  51. triggerFields: ['field1Switch'],
  52. },
  53. // 字段名
  54. fieldName: 'field1',
  55. // 界面显示的label
  56. label: '字段1',
  57. },
  58. {
  59. component: 'Input',
  60. dependencies: {
  61. show(values) {
  62. return !!values.field2Switch;
  63. },
  64. triggerFields: ['field2Switch'],
  65. },
  66. fieldName: 'field2',
  67. label: '字段2',
  68. },
  69. {
  70. component: 'Input',
  71. dependencies: {
  72. disabled(values) {
  73. return !!values.field3Switch;
  74. },
  75. triggerFields: ['field3Switch'],
  76. },
  77. fieldName: 'field3',
  78. label: '字段3',
  79. },
  80. {
  81. component: 'Input',
  82. dependencies: {
  83. required(values) {
  84. return !!values.field4Switch;
  85. },
  86. triggerFields: ['field4Switch'],
  87. },
  88. fieldName: 'field4',
  89. label: '字段4',
  90. },
  91. {
  92. component: 'Input',
  93. dependencies: {
  94. rules(values) {
  95. if (values.field1 === '123') {
  96. return 'required';
  97. }
  98. return null;
  99. },
  100. triggerFields: ['field1'],
  101. },
  102. fieldName: 'field5',
  103. help: '当字段1的值为`123`时,必填',
  104. label: '动态rules',
  105. },
  106. {
  107. component: 'Select',
  108. componentProps: {
  109. allowClear: true,
  110. class: 'w-full',
  111. filterOption: true,
  112. options: [
  113. {
  114. label: '选项1',
  115. value: '1',
  116. },
  117. {
  118. label: '选项2',
  119. value: '2',
  120. },
  121. ],
  122. placeholder: '请选择',
  123. showSearch: true,
  124. },
  125. dependencies: {
  126. componentProps(values) {
  127. if (values.field2 === '123') {
  128. return {
  129. options: [
  130. {
  131. label: '选项1',
  132. value: '1',
  133. },
  134. {
  135. label: '选项2',
  136. value: '2',
  137. },
  138. {
  139. label: '选项3',
  140. value: '3',
  141. },
  142. ],
  143. };
  144. }
  145. return {};
  146. },
  147. triggerFields: ['field2'],
  148. },
  149. fieldName: 'field6',
  150. help: '当字段2的值为`123`时,更改下拉选项',
  151. label: '动态配置',
  152. },
  153. {
  154. component: 'Input',
  155. fieldName: 'field7',
  156. label: '字段7',
  157. },
  158. ],
  159. // 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
  160. wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-4',
  161. });
  162. const [SyncForm] = useVbenForm({
  163. handleSubmit: onSubmit,
  164. schema: [
  165. {
  166. component: 'Input',
  167. // 字段名
  168. fieldName: 'field1',
  169. // 界面显示的label
  170. label: '字段1',
  171. },
  172. {
  173. component: 'Input',
  174. componentProps: {
  175. disabled: true,
  176. },
  177. dependencies: {
  178. trigger(values, form) {
  179. form.setFieldValue('field2', values.field1);
  180. },
  181. // 只有指定的字段改变时,才会触发
  182. triggerFields: ['field1'],
  183. },
  184. // 字段名
  185. fieldName: 'field2',
  186. // 界面显示的label
  187. label: '字段2',
  188. },
  189. ],
  190. // 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
  191. wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-4',
  192. });
  193. function onSubmit(values: Record<string, any>) {
  194. message.success({
  195. content: `form values: ${JSON.stringify(values)}`,
  196. });
  197. }
  198. function handleDelete() {
  199. formApi.setState((prev) => {
  200. return {
  201. schema: prev.schema?.filter((item) => item.fieldName !== 'field7'),
  202. };
  203. });
  204. }
  205. function handleAdd() {
  206. formApi.setState((prev) => {
  207. return {
  208. schema: [
  209. ...(prev?.schema ?? []),
  210. {
  211. component: 'Input',
  212. fieldName: `field${Date.now()}`,
  213. label: '字段+',
  214. },
  215. ],
  216. };
  217. });
  218. }
  219. function handleUpdate() {
  220. formApi.setState((prev) => {
  221. return {
  222. schema: prev.schema?.map((item) => {
  223. if (item.fieldName === 'field3') {
  224. return {
  225. ...item,
  226. label: '字段3-修改',
  227. };
  228. }
  229. return item;
  230. }),
  231. };
  232. });
  233. }
  234. </script>
  235. <template>
  236. <Page
  237. description="表单组件动态联动示例,包含了常用的场景。增删改,本质上是修改schema,你也可以通过 `setState` 动态修改schema。"
  238. title="表单组件"
  239. >
  240. <Card title="表单动态联动示例">
  241. <template #extra>
  242. <Button class="mr-2" @click="handleUpdate">修改字段3</Button>
  243. <Button class="mr-2" @click="handleDelete">删除字段7</Button>
  244. <Button @click="handleAdd">添加字段</Button>
  245. </template>
  246. <Form />
  247. </Card>
  248. <Card class="mt-5" title="字段同步,字段1数据与字段2数据同步">
  249. <SyncForm />
  250. </Card>
  251. </Page>
  252. </template>