当前位置:   article > 正文

element-ui form表单,内嵌表单数据校验_element ui drawer 嵌套表单

element ui drawer 嵌套表单

在最近开发的功能的过程中,遇到一个很复杂的表单;外层一个大表单;里面有一项是动态添加的,而且内嵌一个表单。每一项还有校验规则;如下图

记录一下调试结果。 无论多少层form, 注意几个事项;

form的model/ref;  form_item的prop这个关系到,校验作用具体那个框框 

数据还一个json,组件只是渲染UI,逐步分解就好了。

直接上完整代码,如下:

  1. <!--定义巡检项-->
  2. <template>
  3. <div class="drawer__content">
  4. <el-form :model="formUp" ref="formUp">
  5. <el-form-item
  6. label="巡检项名称"
  7. prop="name"
  8. :label-width="formLabelWidth"
  9. :rules="[
  10. { required: true, message: '请输入巡检项名称', trigger: 'blur' },
  11. ]"
  12. >
  13. <el-input
  14. v-model="formUp.name"
  15. autocomplete="off"
  16. maxlength="64"
  17. ></el-input>
  18. </el-form-item>
  19. <el-form-item
  20. label="巡检项描述"
  21. prop="description"
  22. :label-width="formLabelWidth"
  23. :rules="[
  24. { required: false, message: '请输入巡检项描述', trigger: 'blur' },
  25. ]"
  26. >
  27. <el-input
  28. v-model="formUp.description"
  29. type="textarea"
  30. autocomplete="off"
  31. maxlength="200"
  32. show-word-limit
  33. ></el-input>
  34. </el-form-item>
  35. <el-form-item
  36. label="巡检项登录用户"
  37. prop="itemLevels"
  38. :label-width="formLabelWidth"
  39. :rules="[
  40. {
  41. required: true,
  42. message: '请选择巡检项登录用户',
  43. trigger: 'change',
  44. },
  45. ]"
  46. >
  47. <el-checkbox-group v-model="formUp.itemLevels">
  48. <el-checkbox
  49. label="root"
  50. name="type"
  51. :disabled="formUp.itemLevels.includes('oracle')"
  52. ></el-checkbox>
  53. <el-checkbox
  54. label="administrator"
  55. name="type"
  56. class="borderRight"
  57. :disabled="formUp.itemLevels.includes('oracle')"
  58. ></el-checkbox>
  59. <el-checkbox
  60. label="oracle"
  61. name="type"
  62. :disabled="
  63. formUp.itemLevels.includes('root') ||
  64. formUp.itemLevels.includes('administrator')
  65. "
  66. ></el-checkbox>
  67. </el-checkbox-group>
  68. </el-form-item>
  69. <el-form-item
  70. label="巡检项分类"
  71. prop="itemCategoryId"
  72. :label-width="formLabelWidth"
  73. :rules="[
  74. { required: false, message: '请选择巡检项分类', trigger: 'change' },
  75. ]"
  76. >
  77. <el-cascader
  78. v-model="formUp.itemCategoryId"
  79. clearable
  80. :filterable="true"
  81. :props="{
  82. value: 'id',
  83. label: 'name',
  84. children: 'children',
  85. emitPath: 'false',
  86. checkStrictly: true,
  87. }"
  88. :options="folderData"
  89. :show-all-levels="false"
  90. >
  91. <template slot-scope="{ node, data }">
  92. <span>{{ data.name }}</span>
  93. </template>
  94. </el-cascader>
  95. </el-form-item>
  96. <el-form-item
  97. label="资源分类"
  98. prop="resourceCateId"
  99. :label-width="formLabelWidth"
  100. :rules="[
  101. { required: true, message: '请选择资源分类', trigger: 'change' },
  102. ]"
  103. >
  104. <el-select
  105. v-model="formUp.resourceCateId"
  106. placeholder="请选择资源分类"
  107. @change="getTemplateArr"
  108. :disabled="setDialogType == 'edit'"
  109. >
  110. <el-option
  111. v-for="resourceItem in resourceArr"
  112. :key="resourceItem.id"
  113. :label="resourceItem.name"
  114. :value="resourceItem.id"
  115. ></el-option>
  116. </el-select>
  117. </el-form-item>
  118. <el-form-item
  119. label="结果判定"
  120. prop="resultCheck"
  121. :label-width="formLabelWidth"
  122. >
  123. <el-switch
  124. v-model="formUp.resultCheck"
  125. active-text="有"
  126. inactive-text="无"
  127. >
  128. </el-switch>
  129. </el-form-item>
  130. <el-form-item :label-width="formLabelWidth">
  131. <div slot="label">
  132. <span
  133. ><i style="color: #f56c6c; margin-right: 4px">*</i
  134. >能力模板及表达式配置</span
  135. >
  136. </div>
  137. <div class="addForm">
  138. <el-button
  139. type="primary"
  140. icon="el-icon-circle-plus"
  141. @click="addTemplate(formUp.templateConfigList)"
  142. >增加能力模板</el-button
  143. >
  144. </div>
  145. <div class="formContent">
  146. <div
  147. class="formItem"
  148. v-for="(itemForm, indexA) in formUp.templateConfigList"
  149. :key="indexA"
  150. >
  151. <h4>
  152. 能力模板{{ indexA + 1 }}
  153. <i
  154. style="margin-left: 10px; font-size: 16px; cursor: pointer"
  155. class="el-icon-delete-solid"
  156. v-if="indexA > 0"
  157. @click="deleteTemplate(indexA)"
  158. ></i>
  159. </h4>
  160. <el-form :model="itemForm" :ref="'formDown' + indexA">
  161. <!-- 选择能力模板 -->
  162. <el-form-item
  163. label="选择能力模板"
  164. prop="abilityTemplateId"
  165. :label-width="formLabelWidthB"
  166. :rules="[
  167. {
  168. required: true,
  169. message: '请选择能力模板',
  170. trigger: 'change',
  171. },
  172. ]"
  173. >
  174. <el-select
  175. v-model="itemForm.abilityTemplateId"
  176. placeholder="请选择能力模板"
  177. @change="
  178. changeItemTemplate(itemForm.abilityTemplateId, itemForm)
  179. "
  180. >
  181. <el-option
  182. v-for="(a, index1) in powerArr"
  183. :key="index1"
  184. :label="a.name"
  185. :value="a.id"
  186. ></el-option>
  187. </el-select>
  188. </el-form-item>
  189. <!-- 数据库部署模式 -->
  190. <!-- <el-form-item
  191. v-if="formUp.resultCheck"
  192. label="数据库部署模式"
  193. prop="dbDeployType"
  194. :label-width="formLabelWidthB"
  195. :rules="[
  196. {
  197. required: false,
  198. message: '请选择数据库部署模式',
  199. trigger: 'change',
  200. },
  201. ]"
  202. >
  203. <el-select
  204. v-model="itemForm.dbDeployType"
  205. placeholder="请选择数据库部署模式"
  206. >
  207. <el-option
  208. v-for="(b, index2) in schemaArr"
  209. :key="index2"
  210. :label="b.name"
  211. :value="b.id"
  212. ></el-option>
  213. </el-select>
  214. </el-form-item> -->
  215. <!-- 表达式配置 -->
  216. <el-form-item
  217. v-if="formUp.resultCheck"
  218. :label-width="formLabelWidthB"
  219. >
  220. <div slot="label">
  221. <span
  222. ><i style="color: #f56c6c; margin-right: 4px">*</i
  223. >表达式配置</span
  224. >
  225. <el-tooltip class="item" effect="dark" placement="top-start">
  226. <div slot="content">
  227. <p>1. 符合下述表达式时则判定巡检结果正常;</p>
  228. <p>2. 多个表达式时默认按”逻辑与“的关系处理;</p>
  229. </div>
  230. <i class="el-icon-question"></i>
  231. </el-tooltip>
  232. </div>
  233. <div class="addExpression">
  234. <el-button
  235. type="primary"
  236. icon="el-icon-circle-plus"
  237. @click="itemFormAddRules(itemForm)"
  238. >添加表达式</el-button
  239. >
  240. </div>
  241. <div
  242. class="flexBox"
  243. v-for="(m, indexM) in itemForm.resultCheckRule.rules"
  244. :key="indexM"
  245. >
  246. <div class="expressionItem">
  247. <el-form-item
  248. :prop="`resultCheckRule.rules.` + indexM + '.ruleParam'"
  249. :rules="[
  250. {
  251. validator: (rule, value, callback) =>
  252. checkRuleParam(
  253. rule,
  254. value,
  255. callback,
  256. itemForm.resultCheckRule.rules
  257. ),
  258. trigger: 'change',
  259. },
  260. ]"
  261. >
  262. <el-select
  263. v-model="m.ruleParam"
  264. placeholder="巡检项参数"
  265. clearable
  266. >
  267. <el-option
  268. v-for="(c, index3) in itemForm.ruleParamArr"
  269. :key="index3"
  270. :label="`${c.value}(${c.label})`"
  271. :value-key="c.label"
  272. :value="c"
  273. ></el-option>
  274. </el-select>
  275. </el-form-item>
  276. </div>
  277. <div class="expressionItem">
  278. <el-form-item
  279. :prop="
  280. `resultCheckRule.rules.` + indexM + '.ruleOperator'
  281. "
  282. :rules="[
  283. {
  284. required: true,
  285. message: '请选择数据库部署模式',
  286. trigger: 'change',
  287. },
  288. ]"
  289. >
  290. <el-select
  291. v-model="m.ruleOperator"
  292. placeholder="表达式符号"
  293. clearable
  294. >
  295. <el-option
  296. v-for="(d, index4) in itemForm.ruleOperator"
  297. :key="index4"
  298. :label="d.label"
  299. :value-key="d.label"
  300. :value="d"
  301. ></el-option>
  302. </el-select>
  303. </el-form-item>
  304. </div>
  305. <div class="expressionItem">
  306. <el-form-item
  307. :prop="`resultCheckRule.rules.` + indexM + '.ruleValue'"
  308. :rules="[
  309. {
  310. required: true,
  311. message: '请选择表达式符号',
  312. trigger: 'change',
  313. },
  314. ]"
  315. >
  316. <el-input
  317. v-model="m.ruleValue"
  318. placeholder="请输入参数值"
  319. ></el-input>
  320. </el-form-item>
  321. </div>
  322. <div class="delBtn">
  323. <i
  324. v-if="indexM > 0"
  325. class="el-icon-delete-solid"
  326. @click="itemFormDeleteRules(itemForm, indexM)"
  327. ></i>
  328. </div>
  329. </div>
  330. </el-form-item>
  331. </el-form>
  332. </div>
  333. </div>
  334. </el-form-item>
  335. </el-form>
  336. <div class="drawer__footer">
  337. <el-button @click="cancelForm">取 消</el-button>
  338. <el-button
  339. type="primary"
  340. @click="submitForm(setDialogType)"
  341. :loading="loading"
  342. >{{ loading ? "提交中 ..." : "确 定" }}</el-button
  343. >
  344. </div>
  345. </div>
  346. </template>
  347. <script>
  348. import * as requestMethod from "@/api/inspection/inspectionType/index.js";
  349. export default {
  350. props: {
  351. folderData: {
  352. type: Array,
  353. default: () => [],
  354. },
  355. setDialogType: {
  356. type: String,
  357. default: () => "",
  358. },
  359. setDialogData: {
  360. type: Object,
  361. default: () => {},
  362. },
  363. },
  364. data() {
  365. let checkExpression = (rule, value, callback, indexA) => {
  366. console.log("修改的能力模板内容", value);
  367. if (value == "") {
  368. callback("修改的能力模板内容");
  369. } else {
  370. callback();
  371. }
  372. };
  373. let checkRuleParam = (rule, value, callback, rulesArr) => {
  374. console.log("修改的能力模板内容", value);
  375. console.log("rulesArr", rulesArr);
  376. // 校验是否有重复的
  377. let hasRuleParamlength = rulesArr.filter(
  378. (a) => a.ruleParam.label == value.label
  379. ).length;
  380. if (value == "") {
  381. callback("请选择脚本参数");
  382. } else if (hasRuleParamlength > 1) {
  383. callback("脚本参数不能重复");
  384. } else {
  385. callback();
  386. }
  387. };
  388. return {
  389. checkExpression,
  390. checkRuleParam, // 校验表达式参数
  391. loading: false,
  392. // 上班部门表单
  393. formUp: {
  394. name: "", // 名称
  395. description: "", // 描述
  396. itemCategoryId: "", // 巡检项分类
  397. resourceCateId: "", // 资源分类
  398. itemLevels: [], // 用户
  399. resultCheck: true, // 结果判定,默认flase
  400. templateConfigList: [
  401. {
  402. abilityTemplateId: "", // 选择能力模板
  403. // 数据库部署模式,参数去掉了
  404. // dbDeployType: "",
  405. resultCheckRule: {
  406. // 表达式配置
  407. rules: [
  408. {
  409. ruleParam: {
  410. label: "", //
  411. value: "", //
  412. }, // 巡检项参数
  413. ruleOperator: {
  414. label: "",
  415. value: "",
  416. }, // 表达式符合
  417. ruleValue: "", // 参数值
  418. },
  419. ], // 表达式配置
  420. },
  421. ruleParamArr: [], // 巡检项参数,由选择的能力模板决定
  422. ruleOperator: [], // 巡检参数表达式数据源
  423. },
  424. ],
  425. },
  426. formLabelWidth: "170px",
  427. formLabelWidthB: "128px", // 循环表单项宽度
  428. timer: null,
  429. // 数据源部分
  430. resourceArr: [], // 资源分类数据源
  431. powerArr: [], // 能力模板数据源
  432. schemaArr: [], // 数据库部署模式数据源
  433. // parameterArr: [], // 巡检项参数,数据源
  434. // 巡检项分类展示取参
  435. showProps: {
  436. value: "id",
  437. label: "name",
  438. },
  439. };
  440. },
  441. created() {
  442. // 此处接口获取数据源,下面模拟数据
  443. this.getResourceArr();
  444. },
  445. mounted() {
  446. console.log("row", this.setDialogData);
  447. if (this.setDialogType == "edit") {
  448. let {
  449. name,
  450. description,
  451. itemCategoryId,
  452. resourceCateId,
  453. itemLevels,
  454. resultCheck,
  455. templateConfigList,
  456. } = this.setDialogData;
  457. this.formUp.name = name; // 名称
  458. this.formUp.description = description; // 描述
  459. this.formUp.itemCategoryId = [itemCategoryId]; // 巡检项分类
  460. this.formUp.resourceCateId = resourceCateId; // 资源分类
  461. this.formUp.itemLevels = itemLevels; // 用户
  462. this.formUp.resultCheck = resultCheck; // 结果判定,默认flase
  463. this.formUp.templateConfigList = templateConfigList.map((a) => {
  464. let objTemplateConfig = {
  465. abilityTemplateId: a.abilityTemplateId,
  466. abilityTemplateName: a.abilityTemplateName,
  467. resultCheckRule: a.resultCheckRule,
  468. ruleParamArr: [], // 巡检项参数,由选择的能力模板决定
  469. ruleOperator: [], // 巡检参数表达式数据源
  470. };
  471. return objTemplateConfig;
  472. });
  473. // 根据资源分类,查询模板参数数据源,处理配置templateConfigList每项的ruleParamArr/ruleOperator
  474. this.editFormUpTemplateList(resourceCateId); //
  475. }
  476. // 部署模式固定数据
  477. // this.schemaArr = [
  478. // { id: "RAC", name: "RAC" },
  479. // { id: "Single", name: "单节点" },
  480. // { id: "PowerHA", name: "powerHA" },
  481. // ];
  482. },
  483. methods: {
  484. // 获取资源分类
  485. getResourceArr() {
  486. requestMethod.getResoureConfig("get").then((res) => {
  487. if (res.status || res.code == 200) {
  488. this.resourceArr = res.data;
  489. }
  490. });
  491. },
  492. // 资源分类修改,获取对应的能力模板数据
  493. getTemplateArr(e) {
  494. console.log("选择的资源分类", e);
  495. let parmas = {
  496. resourceCateId: e,
  497. };
  498. requestMethod.getTemplateConfig("get", parmas).then((res) => {
  499. if (res.status || res.code == 200) {
  500. this.powerArr = res.data;
  501. }
  502. });
  503. },
  504. editFormUpTemplateList(id) {
  505. let parmas = {
  506. resourceCateId: id,
  507. };
  508. requestMethod.getTemplateConfig("get", parmas).then((res) => {
  509. let that = this;
  510. if (res.status || res.code == 200) {
  511. this.powerArr = res.data;
  512. let zzPowerArr = res.data;
  513. // 处理现有的数据
  514. this.formUp.templateConfigList = this.formUp.templateConfigList.map(
  515. (m) => {
  516. zzPowerArr.map((n) => {
  517. if (n.id == m.abilityTemplateId) {
  518. m.ruleParamArr = that.objToArray(n.downParaStruct); // 巡检项参数,由选择的能力模板决定
  519. m.ruleOperator = n.ruleOperators; // 巡检参数表达式数据源
  520. }
  521. return true;
  522. });
  523. return m;
  524. }
  525. );
  526. }
  527. });
  528. },
  529. // 当前能力模板的,模板修改,查询对应的表达式参数以及数据源
  530. changeItemTemplate(abilityTemplateId, itemForm) {
  531. console.log("templateId", abilityTemplateId);
  532. console.log("itemForm", itemForm);
  533. requestMethod.getTemplateKeys("get", abilityTemplateId).then((res) => {
  534. if (res.status || res.code == 200) {
  535. itemForm.ruleParamArr = this.objToArray(res.data.downParaStruct); // 当前模板的巡检参数数据源
  536. itemForm.ruleOperator = res.data.ruleOperators; // 当前模板表达式数据源
  537. }
  538. });
  539. },
  540. // 把对象属性参数,转成数组对象
  541. objToArray(obj) {
  542. return Object.entries(obj).map(([name, value]) => ({
  543. label: value.note,
  544. value: name,
  545. type: value.valueType,
  546. // required: value.required,
  547. }));
  548. },
  549. // 能力模板新增表达式
  550. itemFormAddRules(itemForm) {
  551. let obj = {
  552. ruleParam: {
  553. label: "", //
  554. value: "", //
  555. }, // 巡检项参数
  556. ruleOperator: {
  557. label: "",
  558. value: "",
  559. }, // 表达式符合
  560. ruleValue: "", // 参数值
  561. };
  562. itemForm.resultCheckRule.rules = [...itemForm.resultCheckRule.rules, obj];
  563. },
  564. // 能力模板表单删除表达式
  565. itemFormDeleteRules(itemForm, indexM) {
  566. itemForm.resultCheckRule.rules.splice(indexM, 1);
  567. },
  568. // 新增大块的能力模板
  569. addTemplate(templateConfigList) {
  570. let templateObject = {
  571. abilityTemplateId: "", // 选择能力模板
  572. // dbDeployType: "", // 数据库部署模式
  573. resultCheckRule: {
  574. // 表达式配置
  575. rules: [
  576. {
  577. ruleParam: {
  578. label: "", //
  579. value: "", //
  580. }, // 巡检项参数
  581. ruleOperator: {
  582. label: "",
  583. value: "",
  584. }, // 表达式符合
  585. ruleValue: "", // 参数值
  586. },
  587. ], // 表达式配置
  588. },
  589. ruleParamArr: [], // 巡检项参数,由选择的能力模板决定
  590. ruleOperator: [], // 巡检参数表达式数据源
  591. };
  592. this.formUp.templateConfigList = [...templateConfigList, templateObject];
  593. },
  594. // 删除大块的能力模板
  595. deleteTemplate(indexA) {
  596. this.formUp.templateConfigList.splice(indexA, 1);
  597. },
  598. // 取消
  599. cancelForm() {
  600. this.loading = false;
  601. this.$emit("closeSetDialog");
  602. },
  603. // 确定
  604. submitForm(type) {
  605. this.$refs["formUp"].validate((valid) => {
  606. if (valid) {
  607. // 把itemCategoryId重数组转成字符串
  608. this.formUp.itemCategoryId = this.formUp.itemCategoryId.join();
  609. let vo = this.formUp;
  610. let xjxId = type == "edit" ? this.setDialogData.id : ""; // 巡检项Id
  611. if (type == "add") {
  612. requestMethod.setInspection("post", vo).then((res) => {
  613. if (res.status) {
  614. this.$message.success("定义巡检项成功");
  615. // 按照左侧数据筛选,重新获取列表数据
  616. this.$emit("closeSetDialog", "getList");
  617. }
  618. });
  619. } else if (type == "edit") {
  620. requestMethod.editInspection("put", vo, xjxId).then((res) => {
  621. if (res.status) {
  622. this.$message.success("配置巡检项成功");
  623. // 按照左侧数据筛选,重新获取列表数据
  624. this.$emit("closeSetDialog", "getList");
  625. }
  626. });
  627. }
  628. } else {
  629. return false;
  630. }
  631. });
  632. },
  633. },
  634. };
  635. </script>
  636. <style lang='less' scoped>
  637. .drawer__content {
  638. padding: 15px;
  639. display: flex;
  640. flex-direction: column;
  641. height: 100%;
  642. overflow: auto;
  643. form {
  644. flex: 1;
  645. }
  646. .borderRight {
  647. border-right: 1px solid #d9dde0;
  648. padding-right: 30px;
  649. }
  650. }
  651. .drawer__footer {
  652. text-align: right;
  653. border-top: 1px solid #e7edf3;
  654. padding-top: 10px;
  655. }
  656. // 能力模板样式处理
  657. .formContent {
  658. margin-top: 10px;
  659. .formItem {
  660. border: 1px solid #e7edf3;
  661. padding: 0 10px;
  662. h4 {
  663. border-bottom: 1px solid #e7edf3;
  664. margin-bottom: 15px;
  665. }
  666. .addExpression {
  667. margin-bottom: 15px;
  668. }
  669. .flexBox {
  670. display: flex;
  671. align-items: flex-start;
  672. .expressionItem {
  673. flex: 1;
  674. margin-right: 10px;
  675. }
  676. .delBtn {
  677. width: 30px;
  678. font-size: 16px;
  679. cursor: pointer;
  680. }
  681. }
  682. }
  683. }
  684. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/638557
推荐阅读
相关标签
  

闽ICP备14008679号