封装form表单

目录

[1. 源码](#1. 源码)

[2. 其他页面引用](#2. 其他页面引用)


ps:请看完看明白再复用

1. 源码

html 复制代码
<template>
  <div style="width: 100%; height: 100%" class="form-condition">
    <!-- 普通表单 -->
    <el-card shadow="hover" class="cardheight">
      <div class="form-content">
        <el-form ref="FormRef" label-width="auto" :model="FormRef">
          <el-row
            v-for="(formType, indexs) in formTypeArray"
            :key="indexs"
            :gutter="20"
          >
            <!-- <el-button @click="Text(formTypeArray[indexs])"></el-button> -->
            <el-col
              :span="formTypeArray[indexs].length < 2 ? 24 : span"
              v-for="(data, index) in formTypeArray[indexs]"
              :key="index"
            >
              <!-- 关于Id相关的均不显示,此处需要后台进行配合完成 -->
              <!-- &&
                  (data.label
                    ? data.label.includes('ID')
                      ? false
                      : true
                    : false) -->
              <el-form-item
                v-if="
                  data.type !== 'allCheckBox' &&
                  data.type !== 'checkbox' &&
                  (data.label
                    ? data.label.includes('ID')
                      ? false
                      : true
                    : false)
                "
                :label="data.label"
                :prop="data.prop"
                :rules="rules(data)"
              >
                <!-- :label="data.label.includes('ID') ? '序号' : data.label" -->

                <!-- active-text="打开" -->
                <!-- inactive-text="关闭" -->
                <el-switch
                  v-if="data.type == 'switch'"
                  v-model="FormRef[data.prop]"
                  class="mb-2"
                  style="
                    --el-switch-on-color: #13ce66;
                    --el-switch-off-color: #ff4949;
                  "
                  :active-value="1"
                  :inactive-value="0"
                  :disabled="data.disabled"
                  @change="
                    SwitchChang(
                      $event,
                      formTypeArray[indexs][index],
                      indexs,
                      index
                    )
                  "
                />
                <!-- 输入框类型 -->
                <!-- 修改点  去除 v-model.number="FormRef[data.prop]"  202302002-->
                <el-input
                  v-if="data.type == 'input'"
                  v-model="FormRef[data.prop]"
                  :placeholder="data.placeholder"
                  :disabled="data.disabled"
                  suffix-icon="xxxx"
                ></el-input>
                <!-- 时间类型 -->
                <el-date-picker
                  popper-class="date-style"
                  v-if="data.type == 'date'"
                  type="datetime"
                  :placeholder="data.placeholder"
                  v-model="FormRef[data.prop]"
                  format="YYYY/MM/DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  style="width: 100%"
                  :disabled="data.disabled"
                ></el-date-picker>
                <!-- 下拉框类型 -->
                <el-select
                  :popper-append-to-body="false"
                  v-if="data.type == 'select'"
                  :multiple="data.multiple"
                  :clearable="data.clearable"
                  v-model="FormRef[data.prop]"
                  :placeholder="data.placeholder"
                  :change="SelectChange(FormRef[data.prop], data.label)"
                  style="width: 100%"
                  :disabled="data.disabled"
                >
                  <el-option
                    v-for="(item, i) in data.option"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>

                <!-- lu 文本域-->
                <!-- 输入框类型 -->
                <el-input
                  v-if="data.type == 'inputText'"
                  type="textarea"
                  v-model="FormRef[data.prop]"
                  :placeholder="data.placeholder"
                  :disabled="data.disabled"
                  suffix-icon="xxxx"
                ></el-input>

                <el-checkbox
                  v-if="data.type == 'Radio'"
                  :true-label="1"
                  :false-label="0"
                  v-model="FormRef[data.prop]"
                  :label="'点击激活此项为' + data.label + '产品售后信息'"
                  border
                />

                <!-- 显示带有"check-on-click-node"的复选框:树形下拉框 -->
                <el-tree-select
                  v-if="data.type == 'treeSelect'"
                  v-model="FormRef[data.prop]"
                  :data="data.option"
                  check-strictly
                  :render-after-expand="false"
                  show-checkbox
                  check-on-click-node
                  style="width: 100%"
                  :disabled="data.disabled"
                  :multiple="data.multiple"
                />
                <!-- 上传控件 -->
                <el-upload
                  v-if="data.type == 'upload'"
                  action="#"
                  multiple
                  :auto-upload="true"
                  accept="jpg,jpeg,png,PNG"
                  list-type="picture-card"
                  :file-list="files"
                  :http-request="uploadFile"
                  :before-upload="beforeUpload"
                  :on-preview="handlePictureCardPreview"
                  :on-change="ChangeImage"
                  :on-remove="handleRemove"
                >
                  <el-icon><Plus /></el-icon>
                </el-upload>
                <!-- <el-button @click="SubPicForm">提交上传</el-button> -->
                <el-dialog v-model="dialogVisible">
                  <img style="width: 100%" :src="dialogImageUrl" alt="" />
                </el-dialog>
              </el-form-item>
              <el-row
                v-if="
                  data.type == 'allCheckBox' &&
                  JSON.stringify(data.childList) !== '{}'
                "
                class="allcheckBoxOther"
              >
                <el-form-item label-width="auto" label="随带资料">
                  <div v-for="(checkBoxData, key) in data.childList" :key="key">
                    <el-form-item label-width="auto">
                      <el-checkbox
                        border
                        :true-label="1"
                        :false-label="0"
                        :label="checkBoxData.label"
                        v-model="FormRef[checkBoxData.prop]"
                      >
                      </el-checkbox>
                    </el-form-item>
                  </div>
                </el-form-item>
              </el-row>
            </el-col>
          </el-row>
          <el-row style="width: 100%; height: 32px; padding-top: 10px">
            <el-col :span="span" style="width: 100%; margin: 0 auto">
              <el-form-item style="width: 100%">
                <div class="content-btn" style="margin: auto">
                  <el-button
                    plain
                    type="danger"
                    style="float: left; margin-right: 15px"
                    @click="cleanFormValue"
                    ><el-icon><FolderRemove /></el-icon>&ensp; 清 空</el-button
                  >

                  <el-button
                    plain
                    type="primary"
                    style="float: left"
                    @click="getCondition()"
                    ><el-icon><Search /></el-icon>&ensp;{{
                      isOpenSonDataTable || isOpenSonTransfer ? "保存" : "提 交"
                    }}</el-button
                  >
                </div>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </el-card>

    <!-- 是否存在明细附表 -->
    <div v-if="isOpenSonDataTable">
      <!-- 表单 -->
      <el-card shadow="hover">
        <!-- 表单按钮组件 -->
        <div style="margin-bottom: 10px">
          <ButtonView ref="ButtonRef" @ButtonMessage="GetBtnClick"></ButtonView>
        </div>
        <!-- 数据表格组件 -->
        <div class="aa">
          <TableDialog
            ref="tableSonDataRef"
            @getPage="GetDataFenYeWath"
            @tableMessage="GetTableMessage"
          ></TableDialog>
        </div>
      </el-card>
    </div>
    <!-- 抽屉,明细表编辑处 :before-close="drawerCloseSonForm"-->
    <el-drawer
      :key="itemKey"
      :title="dialogTitle"
      v-model="dialog"
      direction="ltr"
      :size="drawerSize"
      custom-class="demo-drawer"
      ref="drawer"
      destroy-on-close
    >
      <div class="demo-drawer__content">
        <!-- 表单组件 -->
        <FromView
          ref="SonfromView"
          @conditionParams="GetCondition"
          @conditionFormData="GetConditionFormData"
          @SonSelectChange="GetSonSelectChange"
        ></FromView>
      </div>
    </el-drawer>
    <!-- 是否存在其他组件 -->
    <div v-if="isOpenSonTransfer">
      <el-card shadow="hover" style="height: 439px">
        <p style="text-align: center; margin: 0 0 20px">
          请选择左侧的数据项,点击中间">"按钮添加数据项
        </p>
        <div style="text-align: center">
          <div>
            <el-transfer
              style="text-align: left; display: inline-block"
              v-model="transferValue"
              :data="transferDatas"
              :props="{
                label: 'title',
              }"
              filterable
              :titles="['待选数据', '已选数据']"
              :button-texts="['取消', '选择']"
            ></el-transfer>
          </div>
          <el-button plain class="squan" type="success" @click="Authorization()"
            >绑 定</el-button
          >
        </div>
      </el-card>
    </div>
  </div>
</template>

<script>
import { computed, provide, inject, ref } from "@vue/runtime-core";
import { watchEffect, getCurrentInstance, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";

export default {
  name: "FromView",
  emits: ["conditionParams"],
  setup(props, context) {
    let FormRefTest = reactive({});
    let span = ref(6); //6
    let formTypeArray = ref(new Array());
    //用于接收父组件传递的Form表单配置
    const formTypeConfig = inject("formTypeConfig");
    //行数
    let formRowsCount = inject("formRowsCount");
    let checkBoxList = [
      {
        type: "allCheckBox",
        label: "allCheckBox",
        childList: {},
      },
    ];

    //移位,将特定的元素移到最后
    function moveArray(arr, sourceIndex, targetIndex) {
      // splice 将目标元素替换并将原结果扔回来赋值给它
      arr[sourceIndex] = arr.splice(targetIndex, 1, arr[sourceIndex])[0];
    }
    /**
     * 设置表单类型
     * @param array 表单配置
     * @param col 每行表单项个数
     */
    const setFormType = (oldArray, col) => {
      formTypeArray = ref(new Array());
      //console.log("进入FormView组件中的方法", formTypeArray);
      //console.log(oldArray, col);
      let array = [];
      oldArray.map((item) => {
        if (item.type == "checkbox") {
          checkBoxList[0].childList[item.prop] = item;
          array.push(item);
        } else {
          array.push(item);
        }
      });

      //console.log("checkBoxList====", checkBoxList);
      //console.log("array====", array);
      //#region 移动 checkbox 参数位置
      //移动
      var sourceIndexes = [];
      array.forEach((item, index) => {
        if (item.type && item.type == "checkbox") {
          sourceIndexes.push(index);
        }
      });
      // 遍历索引数组,移动元素
      sourceIndexes.forEach((sourceIndex) => {
        moveArray(array, sourceIndex, array.length);
      });
      //过滤undefined
      array = array.filter((item) => {
        return item !== undefined || !!item;
      });
      //#endregion
      if (col == null || col == "" || array == null || array == "") {
        col = 4; // 默认分4列
      }
      span.value = 24 / col;
      if (array != null) {
        array.map((item) => {
          FormRefTest[item.prop] = item.value;
        });

        //console.log("==========FormRef=====", FormRefTest);
        // 只有一行
        if (col >= array.length) {
          formTypeArray.value.push(array);
        } else {
          // 超过一行
          let deb = col;
          let i = 0;
          while (i < array.length) {
            let item = []; //null
            var isFlag = false; //当它为True时,下方将不再Push
            while (i < deb) {
              if (array[i].label.indexOf("后台自增ID") !== -1) {
                item.push(array[i]);
                i++;
                break;
              } else if (
                array[i].label.indexOf("备注") !== -1 ||
                array[i].label.indexOf("概述") !== -1 ||
                array[i].label.indexOf("附件") !== -1 ||
                array[i].type.indexOf("inputText") !== -1
              ) {
                //说明在此之前已有数据
                if (item.length > 0) {
                  isFlag = true;
                  formTypeArray.value.push(item);
                  item = [];
                }
                item.push(array[i]);
                i++;
                break;
              } else {
                item.push(array[i]);
                //console.log(deb);
                i++;
              }
            }
            if (!isFlag) {
              formTypeArray.value.push(item);
            }
            if (array.length - i < col) {
              deb = array.length;
            } else {
              deb = i + col;
            }
          }
          formTypeArray.value.push(checkBoxList);
        }
      }

      //console.log("---------表单配置数据 SUCCESS----------");
    };

    //#region 明细表配置
    //用于监听子表表单数据
    let FatherisOk = ref(false);
    //用于父表单保存后的Id
    let FatherIds = ref(0);
    //用于监听子表单中的数据
    let SonConfigCondition = ref([]);
    //用于监听子表一行几个
    let SonformRowsCount = ref(1);
    //明细表单配置
    const ConfigurationCondition = () => {
      provide("formTypeConfig", SonConfigCondition);
      provide("formRowsCount", SonformRowsCount);
    };
    //#endregion

    //#region 穿梭框配置

    //#endregion

    // 监听表单配置数据 数据变化时, 更新配置
    watchEffect(() => {
      //console.log("-------监听formTypeConfig--------");
      //console.log("=formTypeConfig==========", formTypeConfig);
      //console.log(formRowsCount);

      var rowlCount = formRowsCount == undefined ? 1 : formRowsCount.value;

      setFormType(formTypeConfig.value, rowlCount);
    });

    return {
      formTypeArray,
      span,
      //cleanFormValue,
      setFormType,
      ConfigurationCondition, //明细表单配置
      SonConfigCondition,
      FatherisOk, //用于子表判断附表是否已经保存
      FatherIds, //若主表已经保存,此字段不为0且同时可以获取主表新增数据后的Id
      formRowsCount, //行数
      //#region 穿梭框配置
      FormRefTest,
      //#endregion
    };
  },
  data() {
    return {
      FormRef: {},
      checkBoxList: {},
      isOpenSonDataTable: false, //是否存在明细表格
      isOpenSonTransfer: false, //是否存在其他组件
      listData: [], //此处我子表单中选择的数据,用于对其修改、删除使用
      GetDataFenYe: null, //分页查询数据
      GetDataHanderAndFrom: null, //明细表表头查询数据
      dialog: false,
      dialogTitle: "",
      itemKey: "",
      transferValue: [], //穿梭框选中的
      transferDatas: [], //穿梭框数据源
      //上传如下:
      files: [],
      dialogVisible: false,
      dialogImageUrl: "",
      deleteFiles: [],
      //抽屉大小
      drawerSize: "22%",
    };
  },
  created() {
    //默认初始化明细表单配置
    this.ConfigurationCondition();
    this.FormRef = this.FormRefTest;
    //console.log("this.FormRef====", this.FormRef);
    //console.log("this.FormRefTest====", this.FormRefTest);
  },
  methods: {
    Text(val) {},
    rules(data) {
      //#region 自定义验证校验
      if (data.isRules) {
        //校验数值类型
        if (data.propTypes == "INT") {
          var validatorTel = (rule, value, callback) => {
            if (!value) {
              return callback(new Error(data.label + "不能为空"));
            }
            var numReg = /^[0-9]+$/;
            var numRe = new RegExp(numReg);
            if (!numRe.test(value)) {
              callback(new Error("请输入数字值"));
            } else {
              callback();
            }
          };
          return [
            {
              required: true,
              validator: validatorTel,
              trigger: "blur",
            },
          ];
        }
      }
      //#endregion

      //校验手机号 regMobile
      //暂时屏蔽校验手机号,此处不完善,目前只打开校验是否为空
      //20230202留
      // const regMobile =
      //   /^((\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14})|([1][3,4,5,6,7,8,9][0-9]{9})$/;
      // if (data.prop.includes("Tel")) {
      //   var validatorTel = (rule, value, callback) => {
      //     if (!value) {
      //       return callback(new Error(data.label + "不能为空"));
      //     }
      //     var numReg = /^[0-9]+$/;
      //     var numRe = new RegExp(numReg);
      //     if (!numRe.test(value)) {
      //       callback(new Error("请输入数字值"));
      //     } else {
      //       if (!regMobile.test(value)) {
      //         callback(new Error("请输入正确的号码"));
      //       } else {
      //         callback();
      //       }
      //     }
      //   };
      //   return [
      //     {
      //       required: true,
      //       validator: validatorTel,
      //       trigger: "blur",
      //     },
      //   ];
      // } else
      if (
        data.prop == "LoginAccount" ||
        data.prop == "Password" ||
        data.prop.includes("Eqipment") ||
        data.prop == "ProductID" ||
        data.prop == "PartID" ||
        data.prop == "WorkNo" ||
        data.prop == "QualityCode"
      ) {
        if (data.type === "select") {
          return [
            { required: true, message: "此处为必填项", trigger: "change" },
          ];
        }
        if (data.type === "input") {
          return [{ required: true, message: "此处为必填项", trigger: "blur" }];
        }
      }
    },
    SwitchChang(data, formData, indexs, index) {
      // this.FormRef[data.prop] = data ? 1 : 0;
      //
    },
    //实时监听子组件发送的信息
    GetDataFenYeWath(Msg) {
       
      //重新赋值,避免新增、修改、删除操作
      this.pageSize = Msg.pageSize;
      this.pageNum = Msg.pageNum;
      let param = {
        params: Msg,
      };

      if (this.GetDataFenYe != null) {
        this.GetDataFenYe(param);
      }
       this.$emit("SongetPage", { pageSize: this.pageSize, pageNum: this.pageNum });
    },
    //获取表格组件传递的信息
    GetTableMessage(msg) {
      //获取listDatas值
      this.listData =
        msg.type === "列表选择"
          ? msg.listData
          : msg.type === "页码切换"
          ? null
          : null;
      //console.log("组件:表格发送信息:" + this.listData);
    },
    //选择框事件
    SelectChange(data, labels) {
      console.log(labels);
      var linsDatas = { value: data, label: labels };

      //匹配新格式
      var datas = {
        data: linsDatas,
        type: "选择",
      };
      //选择框事件,回传给父组件
      this.$emit("SonSelectChange", datas);
    },
    /**
     * 获取父组件传递过来的数据信息链,这里指isOpenSonTransfer 穿梭框的数据
     */
    SetDataSonTransfer(SonDataTransFer) {
      this.isOpenSonTransfer = SonDataTransFer.isOpenSonTransfer; //是否开启穿梭框
      var tData = SonDataTransFer.SonTransfer; //穿梭框左侧数据
      //为True的情况下,进行渲染明细
      if (this.isOpenSonTransfer) {
        //每次选择后清空,重新触发
        this.transferDatas = [];
        this.transferDatas = tData;
      }
    },
    /**
     * 获取父组件传递过来的数据信息链,这里指isOpenSonTransfer 穿梭框的数据
     */
    SetDataSonTransferDatas(SonDataTransFer) {
      this.isOpenSonTransfer = SonDataTransFer.isOpenSonTransfer; //是否开启穿梭框
      var SonTransferValue = SonDataTransFer.SonTransferValue; //穿梭框右侧数据
      //为True的情况下,进行渲染明细
      if (this.isOpenSonTransfer) {
        //每次选择后清空,重新触发
        this.transferValue = [];
        var ChangeLst = [];
        SonTransferValue.forEach((element) => {
          ChangeLst.push(element.PartID.toString());
        });
        this.transferValue = ChangeLst;
      }
    },
    //绑定按钮
    Authorization() {
      // 优先判断在新增的情况下,主表是否已经完成了保存 多用于子表进行新增操作
      if (!this.FatherisOk) {
        //警告
        this.$message({
          message:
            "在新建明细信息的情况下,请优先添加主表信息,再对其明细表进行新增编辑操作",
          type: "warning",
        });
        return;
      }
      this.formTypeArray;
      this.transferValue;
      var datas = {
        form: this.formTypeArray,
        transDatas: this.transferDatas,
        trans: this.transferValue,
        FatherIds: this.FatherIds,
        type: "绑定",
      };
      this.$emit("SonSelectChange", datas);
    },
    /**
     * 获取父组件传递过来的数据信息链,不包含明细表数据
     * @param {} GetDataLists
     */
    SetData(SonDataTableDatas) {
      this.isOpenSonDataTable = SonDataTableDatas.isOpenSonDataTable;
      //为True的情况下,进行渲染明细
      if (this.isOpenSonDataTable) {
        //渲染 ------ 延迟加载
        this.$nextTick(() => {
          this.$nextTick(() => {
            //自动高度
            this.$refs.tableSonDataRef.heights = "auto";
          });
          //普通表格
          this.$refs.tableSonDataRef.SetTableType(true);
          //组件渲染表头表单
          this.$refs.tableSonDataRef.SetDataTableHeader(
            SonDataTableDatas.GetDataHanderAndFrom
          );
          //添加子表表单数据
          this.SonConfigCondition =
            SonDataTableDatas.GetDataHanderAndFrom.lstSubset[0].Froms;
          //渲染明细按钮
          this.$refs.ButtonRef.SetButtonConfigDatas(
            SonDataTableDatas.PartButtonList
          );
        });
      }
    },
    //接收父组件传递的明细表数据,通过此方法作为媒介进行对孙组件传值
    SetDataSonTable(GetDataFenYe) {
      this.$nextTick(() => {
        //若编辑一条装备主表数据时,存在部件表,此处需要赋值
        this.$refs.tableSonDataRef.SetDataTable(GetDataFenYe);
        // this.dialog = false;
      });
    },
    //获取按钮组件消息------------------------用于明细表单
    GetBtnClick(val) {
      //拿到组件信息后,新增、修改弹出Dalod
      if (val.search("新增") != -1) {
        // 优先判断在新增的情况下,主表是否已经完成了保存 多用于子表进行新增操作
        if (!this.FatherisOk) {
          //警告
          this.$message({
            message:
              "在新建明细信息的情况下,请优先添加主表信息,再对其明细表进行新增编辑操作",
            type: "warning",
          });
          return;
        }
        // 优先添加
        this.dialog = true;
        this.dialogTitle = val;
        // //优先清空
        // this.$refs.SonfromView.CloseSonForm();
        var parm = { type: "新增" };
        this.$emit("GrandsonFormArr", parm);
      }
      if (val.search("编辑") != -1) {
        //仅支持单条编辑
        if (JSON.parse(JSON.stringify(this.listData)).length != 1) {
          //警告
          this.$message({
            message: "请选择一条数据进行编辑操作!",
            type: "warning",
          });
          return;
        }
        //结构剖析
        var newListData = JSON.parse(JSON.stringify(this.listData));

        //循环表单
        this.SonConfigCondition.forEach((item) => {
          newListData.forEach((dataitem) => {
            //循环找Key
            for (let key in dataitem) {
              if (item.prop == key) {
                item.value = dataitem[key];
              }
            }
          });
        });
        //先打开
        this.dialog = true;
        this.dialogTitle = val;
        if (
          newListData[0].Files !== undefined &&
          newListData[0].Files !== null
        ) {
          //剔除特殊字符
          var newFilesString = newListData[0].Files.replace(/"/g, "");
          //分割数组
          var newFilesArr = newFilesString.replace(/"/g, "").split("|");
          //删除最后一位,总是多出的空 ''
          newFilesArr.pop();

          //此处延迟加载会帮你解决一切
          this.$nextTick(() => {
            var newFiles = [];
            //构建回显所需要的参数值
            newFilesArr.forEach((element) => {
              var file = { url: this.$FWurl + element };
              newFiles.push(file);
            });
            //组件渲染
            this.$refs.SonfromView.SetFilesData(newFiles);
          });
        }

        var parm = { type: "编辑", Ids: newListData[0].ID };
        this.$emit("GrandsonFormArr", parm);
      }
      if (val.search("删除") != -1) {
        this.$nextTick(() => {
          var _this = this;
          //仅支持单条编辑
          if (JSON.parse(JSON.stringify(this.listData)).length != 1) {
            //警告
            this.$message({
              message: "请选择一条数据进行删除操作!",
              type: "warning",
            });
            return;
          }
          //结构剖析
          var newListData = JSON.parse(JSON.stringify(this.listData));
          //此参数在删除时无需传递
          delete newListData[0].id;
          ElMessageBox.confirm("确认删除这条信息吗?", "警告", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              let dataParam = { data: newListData[0], type: "删除" };
              this.$emit("SonFormArr", dataParam);
            })
            .catch(() => {});
        });
      }
    },
    //给孙组件的抽屉添加宽度
    SetDrawerSize(value) {
      //渲染 ------ 延迟加载
      this.$nextTick(() => {
        //重新渲染,itemKey用于处理Table不渲染的问题
        this.drawerSize = value;
      });
    },
    //孙组件获取父组件传递的File信息
    GetConditionFormData(datas) {
      // Ids虽然是从父级得来,但是此处可能会丢失Ids,所以需要将孙级位面中Ids获取,也就是明细Id
      //先删后加,垃圾FormData特性

      datas.delete("Ids");
      datas.append("Ids", this.FatherIds); //属于哪条明细表数据
      this.$emit("conditionFormData", datas);
    },
    //获取表单组件传递的信息,此处接收的表单乃是数据表格对应的表单------------------------用于明细表单
    GetCondition(datas) {
      //console.log("组件:表单组件发送信息:" + datas);
      var formDatas = {};
      formDatas = datas;

      // datas.forEach((e, index) => {
      //   for (let i = 0; i < e.length; i++) {
      //     var keys = datas[index][i].prop;
      //     var values = datas[index][i].value;
      //     formDatas[keys] = values;
      //   }
      // });
      const param = formDatas;
      //获取表单组件后,判断是新增/修改
      if (this.dialogTitle.search("新增") != -1) {
        //将新增后的主表Id拿到后进行新增操作,此处需要回传到最外层的组件中
        param.FatherIds = this.FatherIds;
        let dataParam = { data: param, type: "新增" };
        this.$emit("SonFormArr", dataParam);
      }
      if (this.dialogTitle.search("编辑") != -1) {
        param.FatherIds = this.FatherIds;
        let dataParam = { data: param, type: "编辑" };
        this.$emit("SonFormArr", dataParam);
      }
    },

    //清空子表表单数据
    CloseSonForm() {
      //清空选择
      this.cleanFormValue();
    },

    //抽屉回调,关闭前清空表单数据
    drawerCloseSonForm(done) {
      //清空选择
      this.$refs.SonfromView.CloseSonForm();
      done();
    },

    /**
     * 清空表单内容
     */
    cleanFormValue() {
      for (let key in this.FormRef) {
        this.FormRef[key] = "";
      }
    },
    //#region 关于图片组上传
    uploadFile(file) {
      //console.log(file);
    },
    //删除事件
    handleRemove(file, fileList) {
      var obj = file.url.split("upLoad/").slice(-1)[0];
      //添加 需要删除的附件
      this.deleteFiles.push(obj);
      //console.log(file, fileList);
    },
    //预览事件
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    //添加图片
    ChangeImage(file, filelist) {
      this.files = filelist;
      //console.log("-----------" + JSON.stringify(file));
    },
    /**
     * 给父组件返回表单输入的内容
     */

    /// lu
    getCondition() {
      this.$refs.FormRef.validate((valid) => {
        //console.log("valid===", valid);
        if (valid) {
          var formData = new FormData();
          this.files.forEach((item) => {
            if (!(!item.raw && item.url.indexOf("blob") === -1)) {
              formData.append("file", item.raw);
            }
          });

          formData.append("Ids", this.FatherIds); //属于哪条主表数据
          this.deleteFiles.forEach((item) => {
            formData.append("fileByDelete", item); //删除的集合
          });
          // //console.log(333333, this.formTypeArray);
          this.$emit("conditionParams", this.FormRef);
          this.$emit("conditionFormData", formData);
        } else {
          // this.$message("请输入内容");
          return false;
        }
      });
    },
    /**
     * 回显
     */
    SetFilesData(FilesList) {
      //渲染 ------ 延迟加载
      this.$nextTick(() => {
        this.files = [];
        this.files = FilesList;
      });
    },
    //#endregion
    //子组件中选择框事件
    GetSonSelectChange(datas) {
      if (datas.type == "选择") {
        this.$emit("GrandsonSelectChange", datas);
      }
      if (datas.type == "绑定") {
        this.$emit("GrandsonSelectChange", datas);
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.allcheckBoxOther div:not(:first-child) {
  margin-left: 1% !important;
  :deep(.el-form-item__label-wrap) {
    margin-bottom: 20% !important;
    margin-left: 1% !important;
  }
}
.aa ::v-deep .el-scrollbar {
  height: 100px;
}
//卡片与"新增"字样之间的距离,卡片的padding-top 为0
.el-dialog--center .el-dialog__body {
  text-align: initial;
  padding: 0px calc(var(--el-dialog-padding-primary) + 5px) 30px !important;
}
</style>

2. 其他页面引用

html 复制代码
<template>
  <el-row :gutter="20">
    <el-col :span="4">
      <div>
        <!-- 树形列表组件 -->
        <el-collapse v-model="activeNames" @change="handleChange">
          <el-collapse-item style="text-align: center" title="字典项" name="1">
            <TreeView
              ref="TreeRef"
              @TreeViewMessage="GetTreeMessage"
              :defaultSelected="defaultSelected"
              nodeKey="DictID"
            ></TreeView>
          </el-collapse-item>
        </el-collapse>
      </div>
    </el-col>

    <el-divider direction="vertical">分割线</el-divider>

    <el-col :span="19">
      <div>
        <!-- 表单按钮组件 -->
        <div style="margin-bottom: 10px">
          <ButtonView @ButtonMessage="GetBtnClick"></ButtonView>
        </div>
        <!-- 数据表格组件 -->
        <div style="width: 103%">
          <TableDialog
            ref="tableRef"
            @getPage="GetDataFenYeWath"
            @tableMessage="GetTableMessage"
            @treeMessage="GetTreeMessage1"
          ></TableDialog>
        </div></div
    ></el-col>
  </el-row>
  <!-- 弹出框,用于新增、修改 -->
  <el-dialog
    v-model="dialogVisible"
    :title="dialogTitle"
    width="30%"
    center
    draggable
    destroy-on-close
  >
    <!-- 表单组件 -->
    <FromView
      style="margin-top: -25px"
      ref="fromViewRef"
      @conditionParams="GetCondition"
    ></FromView>
  </el-dialog>
  <!-- <el-backtop target=".page-component__scroll .el-scrollbar__wrap"></el-backtop> -->
</template>

<script>
import { provide, reactive, ref } from "@vue/runtime-core";
import { ElMessage, ElMessageBox } from "element-plus";

export default {
  name: "Sys_DictTable",
  data() {
    return {
      activeNames: ["1"], //左侧的折叠用户,默认展开
      dialogVisible: false, //用于控制新增、编辑
      dialogTitle: "", //用于控制新增、编辑标题
      listData: [], //已选择的数据
      Dictid: "",
      defaultSelected: "",
      selectedDictIDs: "", //左侧树勾选的id(多选)
    };
  },
  setup() {
    //默认页大小
    let pageSize = 20;
    let pageNum = 1;
    let total = 0;

    //用于监听选中的数据列表
    let ConfigCondition = ref([]);
    //表单配置
    const ConfigurationCondition = () => {
      provide("formTypeConfig", ConfigCondition);
    };
    //表格配置
    const ConfigurationTable = () => {
      var tableHeader = []; // 设置表头 [fieldName字段名, label列名, width列宽, sortable排序]
      var tableDatas = []; // 表格数据
      // 设置表头 [fieldName字段名, label列名, width列宽, sortable排序]

      // 配置表头数据
      provide("tableHeaderConfig", tableHeader);
      // 配置单元格数据及属性/ 分页配置默认值
      provide("tableDataConfig", {
        tableData: tableDatas,
      });
    };
    //树形列表配置
    const ConfigurationTree = () => {
      provide("TreeConfig", { isTreeSeleteOrBtn: 1 });
    };
    //按钮配置
    const ConfigurationButton = () => {
      let CfgButtonDatas = [];
      CfgButtonDatas = [
        {
          btnName: "新增",
          btnType: "success",
          plain: true, //简约按钮类型,与UI相关
          SvgIconName: "Insert",
        },
        {
          btnName: "编辑",
          btnType: "primary",
          plain: true,
          SvgIconName: "Update",
        },
        {
          btnName: "删除",
          btnType: "danger",
          plain: true,
          SvgIconName: "Delete",
        },
      ];
      provide("ButtonTypes", { type: 1 }); // 通常使用默认 1 按钮
      provide("ButtonConfig", { CfgButtonDatas: CfgButtonDatas });
    };

    //注册高级筛选查询配置、表单配置
    return {
      pageSize,
      pageNum,
      total,
      ConfigCondition, //表单数据,实时传递回
      ConfigurationCondition,
      ConfigurationTable,
      ConfigurationTree,
      ConfigurationButton,
    };
  },
  created() {
    //初始化配置
    this.ConfigurationCondition();
    this.ConfigurationTable();
    this.ConfigurationTree();
    this.ConfigurationButton();
    //加载表单、表格列头
    this.GetColDataList();
    // Get请求下,必须要在对象内添加params 参数,再嵌套一层,否则无法识别
    const param = {
      params: {
        pageSize: this.pageSize,
        pageNum: this.pageNum,
      },
    };
    // this.GetDataFenYe(param);
    //获取部门树形列表
    this.GetDepartMentGetDataTree();
  },
  mounted() {},
  methods: {
    //实时监听子组件发送的信息
    GetDataFenYeWath(Msg) {
      //重新赋值,避免新增、修改、删除操作
      this.pageSize = Msg.pageSize;
      this.pageNum = Msg.pageNum;

      let param = {
        params: Msg,
      };
      this.GetDataFenYe(param);
    },

    //获取用户数据,用户数据绑定在某个模块节点下,默认查询所有
    GetDepartMentGetDataTree() {
      //Get请求下,必须要在对象内添加params 参数,再嵌套一层,否则无法识别
      const param = {
        params: {},
      };
      this.$API
        .DicGetDataTree(param)
        .then((res) => {
          //组件渲染
          // console.log("树", res.data.Data.lstSubset[0].DictID);
          this.defaultSelected = [res.data.Data.lstSubset[0].DictID];
          this.selectedDictIDs = [res.data.Data.lstSubset[0]];

          this.$refs.TreeRef.SetTreeDatas(res.data.Data.lstSubset);
          const param = {
            params: {
              pageSize: this.pageSize,
              pageNum: this.pageNum,
              DictIDs: res.data.Data.lstSubset[0].DictID,
            },
          };
          this.GetDataFenYe(param);
        })
        .catch((err) => {
          // this.$notify.error({
          //   title: "消息提示",
          //   message: err,
          // });
        });
    },

    //获取用户数据,用户数据绑定在某个模块节点下,默认查询所有
    GetColDataList() {
      //Get请求下,必须要在对象内添加params 参数,再嵌套一层,否则无法识别
      const param = {
        params: { param: "1" },
      };
      this.$API
        .DicGetColDataList(param)
        .then((res) => {
          //组件渲染

          this.$refs.tableRef.SetDataTableHeader(res.data.Data);
          //直接将此数据类型贯通至组件中
          this.ConfigCondition = res.data.Data.lstSubset[0].Froms;
        })
        .catch((err) => {
          // this.$notify.error({
          //   title: "消息提示",
          //   message: err,
          // });
        });
    },
    //查询分页数据
    GetDataFenYe(param) {
      this.$API
        .DicGetDataFenYe(param)
        .then((res) => {
          //组件渲染
          console.log("数据", res.data.Data);
          this.$refs.tableRef.SetDataTable(res.data.Data);
        })
        .catch((err) => {
          // this.$notify.error({
          //   title: "消息提示",
          //   message: err,
          // });
        });
    },
    /**
     * 新增
     * @param {*} data
     */
    InsertFormDatas(data) {
      this.$API
        .DicInsertData(data)
        .then((res) => {
          ElMessage({
            type: "success",
            message: res.data.Msg,
          });

          this.CloseForm();
          this.dialogVisible = false;
          const param = {
            params: {
              pageSize: this.pageSize,
              pageNum: this.pageNum,
              DictIDs: data.DictID,
            },
          };
          this.GetDataFenYe(param);
        })
        .catch((err) => {
          this.$notify.error({
            title: "消息提示",
            message: err,
          });
        });
    },
    /**
     * 修改
     * @param {} data
     */
    UpdateFormDatas(data) {
      this.$API
        .DicUpdateData(data)

        .then((res) => {
          ElMessage({
            type: "success",
            message: res.data.Msg,
          });
          this.CloseForm();
          this.dialogVisible = false;
          const param = {
            params: {
              pageSize: this.pageSize,
              pageNum: this.pageNum,
              DictIDs: data.DictID,
            },
          };
          this.GetDataFenYe(param);
        })
        .catch((err) => {
          this.$notify.error({
            title: "消息提示",
            message: err,
          });
        });
    },
    /**
     * 删除
     * @param {*} data
     */
    DeleteFormDatas(data) {
      this.$API
        .DicDeletData(data)
        .then((res) => {
          ElMessage({
            type: "success",
            message: res.data.Msg,
          });
          this.CloseForm();
          this.dialogVisible = false;
          const param = {
            params: {
              pageSize: this.pageSize,
              pageNum: this.pageNum,
              DictIDs: data.DictID,
            },
          };
          this.GetDataFenYe(param);
        })
        .catch((err) => {
          this.$notify.error({
            title: "消息提示",
            message: err,
          });
        });
    },

    //获取表单组件传递的信息,此处接收的表单乃是数据表格对应的表单
    GetCondition(datas) {
      console.log("组件:表单组件发送信息:" + datas);
      var formDatas = {};
      // datas.forEach((e, index) => {
      //   for (let i = 0; i < e.length; i++) {
      //     var keys = datas[index][i].prop;
      //     var values = datas[index][i].value;
      //     formDatas[keys] = values;
      //   }
      // });
      const param = datas;
      //获取表单组件后,判断是新增/修改
      if (this.dialogTitle.search("新增") != -1) {
        this.InsertFormDatas(param);
      }
      if (this.dialogTitle.search("编辑") != -1) {
        console.log("param===========", param);
        this.UpdateFormDatas(param);
      }
    },
    //获取表格组件传递的信息
    GetTableMessage(msg) {
      //获取listDatas值
      this.listData =
        msg.type === "列表选择"
          ? msg.listData
          : msg.type === "页码切换"
          ? null
          : null;
      console.log("组件:表格发送信息:" + this.listData);
    },
    //获取树形组件传递的信息
    GetTreeMessage(val) {
      console.log("valaaa", val.data);
      let NodeList = JSON.parse(JSON.stringify(val.data));
      this.selectedDictIDs = val.data;
      let newParam = "";
      NodeList.forEach((element) => {
        newParam = newParam + element.DictID + ",";
      });
      //去掉最后一个逗号(如果不需要去掉,就不用写)
      if (newParam.length > 0) {
        newParam = newParam.substr(0, newParam.length - 1);
      }
      console.log("--------组件:树形列表解析后:" + newParam);
      const param = {
        params: {
          pageSize: this.pageSize,
          pageNum: this.pageNum,
          DictIDs: newParam,
        },
      };
      this.GetDataFenYe(param);
    },
    //折叠面板用户
    handleChange(val) {},
    //获取按钮组件消息
    GetBtnClick(val) {
      //拿到组件信息后,新增、修改弹出Dalod
      if (val.search("新增") != -1) {
        // this.CloseForm();
        this.$nextTick(() => {
          this.$refs.tableRef.ClearSelect();
        });
        //lu
        if (JSON.parse(JSON.stringify(this.selectedDictIDs)).length != 1) {
          //警告
          this.$message({
            message: "请选择一条字典项进行新增操作!",
            type: "warning",
          });
          return;
        }
        //循环表单
        var newSelectData = JSON.parse(JSON.stringify(this.selectedDictIDs));
        this.ConfigCondition.forEach((item) => {
          newSelectData.forEach((dataitem) => {
            //循环找Key
            for (let key in dataitem) {
              if (item.prop == key && key == "DictID") {
                item.value = dataitem[key];
              }
            }
            // item[0].value = defaultSelected;
          });
        });
        console.log("ConfigCondition===", this.ConfigCondition);

        this.dialogVisible = true;
        this.dialogTitle = val + "字典项";
      }
      if (val.search("编辑") != -1) {
        //仅支持单条编辑
        if (JSON.parse(JSON.stringify(this.listData)).length != 1) {
          //警告
          this.$message({
            message: "请选择一条数据进行编辑操作!",
            type: "warning",
          });
          return;
        }

        //结构剖析
        var newListData = JSON.parse(JSON.stringify(this.listData));

        //循环表单
        this.ConfigCondition.forEach((item) => {
          newListData.forEach((dataitem) => {
            //循环找Key
            for (let key in dataitem) {
              if (item.prop == key) {
                item.value = dataitem[key];
              }
            }
          });
        });

        this.dialogVisible = true;
        this.dialogTitle = val + "字典项";
      }

      if (val.search("删除") != -1) {
        this.$nextTick(() => {
          var _this = this;
          //仅支持单条编辑
          if (JSON.parse(JSON.stringify(this.listData)).length != 1) {
            //警告
            this.$message({
              message: "请选择一条数据进行删除操作!",
              type: "warning",
            });
            return;
          }
          //结构剖析
          var newListData = JSON.parse(JSON.stringify(this.listData));

          ElMessageBox.confirm("确认删除这条信息吗?", "警告", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              _this.DeleteFormDatas(newListData[0]);
            })
            .catch(() => {});
        });
      }
    },
    //清空表单数据,解决选中某行时,点击新增按钮,响应ConfigCondition参数的清空以及取消选择
    CloseForm() {
      this.$nextTick(() => {
        //循环表单清空
        this.ConfigCondition.forEach((item) => {
          item.value = "";
        });
        //清空选择
        this.$refs.tableRef.ClearSelect();
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.el-divider--vertical {
  display: inline-block;
  width: 1px;
  height: 53em;
  margin: 0 8px;
  vertical-align: middle;
  position: relative;
  border-left: 1px var(--el-border-color) var(--el-border-style);
}
</style>
相关推荐
2分钟速写快排16 分钟前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60611 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角2 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!2 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰2 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi4 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen4 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马5 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu5 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss
IT_陈寒5 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端