Basic.vue 8.7 KB

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