Basic.vue 10 KB

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