Basic.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <script lang="ts" setup>
  2. import type { BasicForm } from '@/types/form'
  3. import { ElInput } from 'element-plus'
  4. const request = function ({ pageNo }: any) {
  5. return new Promise(resolve => {
  6. setTimeout(() => {
  7. const data = {
  8. list: [
  9. { name: '张三' + pageNo, sex: '男', id: '' + pageNo + 1 },
  10. { name: '李四' + pageNo, sex: '女', id: '' + pageNo + 2 },
  11. { name: '王五' + pageNo, sex: '男', id: '' + pageNo + 3 },
  12. { name: '赵六' + pageNo, sex: '女', id: '' + pageNo + 4 },
  13. { name: '张三' + pageNo, sex: '男', id: '' + pageNo + 5 }
  14. ],
  15. total: 10
  16. }
  17. resolve(data)
  18. }, 1500)
  19. })
  20. }
  21. const formData = reactive<any>({})
  22. const formConfig = reactive<BasicForm>({
  23. span: 12,
  24. props: {
  25. labelPosition: 'right'
  26. },
  27. formItems: [
  28. {
  29. label: '',
  30. value: '',
  31. name: '',
  32. type: 'form-title',
  33. span: 24,
  34. notFormItem: true,
  35. props: {
  36. title: '基础表单',
  37. type: 'success',
  38. color: '#0366d6'
  39. }
  40. },
  41. {
  42. label: '用户名',
  43. value: '',
  44. name: 'name',
  45. type: 'input',
  46. rules: [{ required: true, message: '请输入用户名', trigger: 'blur' }]
  47. },
  48. {
  49. label: '密码',
  50. value: '',
  51. name: 'password',
  52. type: 'custom',
  53. slots: [
  54. {
  55. name: 'default',
  56. alias: 'password'
  57. }
  58. ],
  59. rules: [{ required: true, message: '请输入密码', trigger: 'blur' }]
  60. },
  61. {
  62. label: '区域',
  63. value: [],
  64. name: 'area',
  65. type: 'area',
  66. props: {
  67. props: {
  68. multiple: true
  69. }
  70. }
  71. },
  72. {
  73. label: '下拉表格',
  74. value: '',
  75. name: 'tableSelect',
  76. type: 'tableSelect',
  77. props: {
  78. tableConfig: {
  79. column: [
  80. {
  81. title: '#',
  82. type: 'seq',
  83. width: 45,
  84. align: 'center'
  85. },
  86. {
  87. title: '姓名',
  88. field: 'name',
  89. align: 'center'
  90. },
  91. {
  92. title: '性别',
  93. align: 'center',
  94. slot: 'sex'
  95. }
  96. ],
  97. /* 实际开发应传入接口方法 */
  98. request: request,
  99. pageSize: 5
  100. }
  101. }
  102. },
  103. {
  104. label: '手机号',
  105. value: '',
  106. name: 'phone',
  107. type: 'input',
  108. rules: [
  109. // {
  110. // validator: validator.mobile
  111. // }
  112. ]
  113. },
  114. {
  115. label: '开关',
  116. value: true,
  117. name: 'ss',
  118. type: 'switch',
  119. props: {}
  120. },
  121. {
  122. label: '',
  123. value: '',
  124. name: '',
  125. type: 'button',
  126. notFormItem: true,
  127. props: {
  128. buttonName: '按钮'
  129. }
  130. },
  131. {
  132. label: '',
  133. value: '',
  134. name: '',
  135. type: 'alert',
  136. notFormItem: true,
  137. props: {
  138. title: 'alert',
  139. type: 'warning'
  140. }
  141. },
  142. {
  143. label: '字典',
  144. value: '',
  145. name: 'field1',
  146. type: 'dict',
  147. props: {
  148. type: 'task_from',
  149. multiple: true
  150. }
  151. },
  152. {
  153. label: '字段名',
  154. value: '',
  155. name: 'field2',
  156. type: 'input',
  157. slots: [
  158. {
  159. name: 'prepend',
  160. alias: 'prepend1'
  161. },
  162. {
  163. name: 'append',
  164. alias: 'append1'
  165. }
  166. ]
  167. },
  168. {
  169. label: '字段名',
  170. value: '',
  171. name: 'field3',
  172. type: 'cascader',
  173. props: {
  174. options: [
  175. {
  176. value: 'guide',
  177. label: 'Guide',
  178. children: [
  179. {
  180. value: 'disciplines',
  181. label: 'Disciplines',
  182. children: [
  183. {
  184. value: 'consistency',
  185. label: 'Consistency'
  186. },
  187. {
  188. value: 'feedback',
  189. label: 'Feedback'
  190. },
  191. {
  192. value: 'efficiency',
  193. label: 'Efficiency'
  194. },
  195. {
  196. value: 'controllability',
  197. label: 'Controllability'
  198. }
  199. ]
  200. },
  201. {
  202. value: 'navigation',
  203. label: 'Navigation',
  204. children: [
  205. {
  206. value: 'side nav',
  207. label: 'Side Navigation'
  208. },
  209. {
  210. value: 'top nav',
  211. label: 'Top Navigation'
  212. }
  213. ]
  214. }
  215. ]
  216. },
  217. {
  218. value: 'resource',
  219. label: 'Resource',
  220. children: [
  221. {
  222. value: 'axure',
  223. label: 'Axure Components'
  224. },
  225. {
  226. value: 'sketch',
  227. label: 'Sketch Templates'
  228. },
  229. {
  230. value: 'docs',
  231. label: 'Design Documentation'
  232. }
  233. ]
  234. }
  235. ]
  236. },
  237. slots: [
  238. {
  239. name: 'default',
  240. alias: 'cDefault'
  241. }
  242. ],
  243. events: {
  244. change() {
  245. formData.name = 'c'
  246. formConfig.formItems[1].hidden = true
  247. }
  248. }
  249. },
  250. {
  251. label: '树选择',
  252. value: '',
  253. name: 'tree',
  254. type: 'tree-select',
  255. props: {
  256. data: [
  257. {
  258. value: '1',
  259. label: 'Level one 1',
  260. children: [
  261. {
  262. value: '1-1',
  263. label: 'Level two 1-1',
  264. children: [
  265. {
  266. value: '1-1-1',
  267. label: 'Level three 1-1-1'
  268. }
  269. ]
  270. }
  271. ]
  272. },
  273. {
  274. value: '2',
  275. label: 'Level one 2',
  276. children: [
  277. {
  278. value: '2-1',
  279. label: 'Level two 2-1',
  280. children: [
  281. {
  282. value: '2-1-1',
  283. label: 'Level three 2-1-1'
  284. }
  285. ]
  286. },
  287. {
  288. value: '2-2',
  289. label: 'Level two 2-2',
  290. children: [
  291. {
  292. value: '2-2-1',
  293. label: 'Level three 2-2-1'
  294. }
  295. ]
  296. }
  297. ]
  298. }
  299. ]
  300. }
  301. },
  302. {
  303. label: '图片',
  304. value: '',
  305. name: 'image',
  306. type: 'image-upload',
  307. slots: [
  308. {
  309. name: 'tip',
  310. alias: 'tip'
  311. }
  312. ]
  313. },
  314. {
  315. label: '文件',
  316. value: 'erp/prod/temp/1702626281947.png,erp/prod/temp/1702626287319.png',
  317. name: 'file',
  318. type: 'file-upload',
  319. slots: [
  320. {
  321. name: 'default',
  322. alias: 'file'
  323. }
  324. ]
  325. },
  326. {
  327. label: '可编辑标签',
  328. value: 'f,ghh',
  329. name: 'tag',
  330. type: 'edit-tag'
  331. },
  332. {
  333. label: '自定义',
  334. value: '',
  335. name: 'custom',
  336. type: 'custom',
  337. notFormItem: true,
  338. slots: [
  339. {
  340. name: 'default',
  341. alias: 'customDefault'
  342. }
  343. ]
  344. }
  345. ]
  346. })
  347. const create = (data: any) => {
  348. console.log(data)
  349. }
  350. const update = (data: any) => {
  351. console.log(data)
  352. }
  353. const proFormRef = ref<any>()
  354. const handleSave = () => {
  355. proFormRef.value.submit()
  356. }
  357. const inputValue = ref('')
  358. const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3'])
  359. const inputVisible = ref(false)
  360. const InputRef = ref<InstanceType<typeof ElInput>>()
  361. const handleClose = (tag: string) => {
  362. dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1)
  363. }
  364. const showInput = () => {
  365. inputVisible.value = true
  366. nextTick(() => {
  367. InputRef.value!.input!.focus()
  368. })
  369. }
  370. const handleInputConfirm = () => {
  371. if (inputValue.value) {
  372. dynamicTags.value.push(inputValue.value)
  373. }
  374. inputVisible.value = false
  375. inputValue.value = ''
  376. }
  377. </script>
  378. <template>
  379. <div class="h-full bg-white p-16px pt-20px overflow-auto">
  380. <form-title type="primary" class="py-10px mb-4">
  381. <template #default> 标题 </template>
  382. </form-title>
  383. <pro-form :formConfig="formConfig" :formData="formData" :create="create" :update="update" ref="proFormRef">
  384. <template #prepend1> test1 </template>
  385. <template #append1> test1 </template>
  386. <template #cDefault="{ node, data }">
  387. <span>{{ data.label }}</span>
  388. <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
  389. </template>
  390. <template #file>
  391. <el-button type="primary">上传文件</el-button>
  392. </template>
  393. <template #tip>
  394. <div><el-text>请上传750*450px 的图片</el-text></div>
  395. </template>
  396. <template #password>
  397. <el-input type="password" name="password" v-model="formData.password" placeholder="请输入密码"></el-input>
  398. <el-text type="info">密码需包含大写字母、小写字母、数字</el-text>
  399. </template>
  400. <template #customDefault>
  401. <el-space wrap>
  402. <el-tag
  403. v-for="tag in dynamicTags"
  404. :key="tag"
  405. size="small"
  406. closable
  407. :disable-transitions="false"
  408. @close="handleClose(tag)"
  409. >
  410. {{ tag }}
  411. </el-tag>
  412. <el-input
  413. v-if="inputVisible"
  414. ref="InputRef"
  415. v-model="inputValue"
  416. class="ml-1 w-20"
  417. size="small"
  418. @keyup.enter="handleInputConfirm"
  419. @blur="handleInputConfirm"
  420. />
  421. <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput"> + New Tag </el-button>
  422. </el-space>
  423. </template>
  424. </pro-form>
  425. <div class="text-center">
  426. <el-button type="primary" @click="handleSave">保存</el-button>
  427. </div>
  428. </div>
  429. </template>
  430. <style lang="scss" scoped></style>