element ui的from表单,不断修改版

,from表单

有两个parmas,展示的数据,rules,校验规则

看代码,虽然没用

1,如果弹窗后关闭弹窗,再打开发现有校验问题,这个需要重置表单,使用resetfields() 方法,这个方法可以对整个表单进行重置,将所有字段值重置为初始值并移除校验结果;

坑:也会清除并初始化所有的默认数据,所以要注意使用

2,如果再点击弹窗,弹窗中有类似于切换的页面的,如

弹出后后面需要往弹窗传数据,并且点击对应的编辑弹出对应的导航数据时,要在关闭弹窗的时候将导航脚标设置为初始值;

export const BASE_FORM = [
  {
    label: '单号',
    key: 'superviseNo',
    type: 'input',
    disabled: true,
    loading: false,
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '事项',
    key: 'superviseDesc',
    type: 'input',
    maxLength: 50,
    loading: false,
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '部门',
    key: 'creatorId',
    labelKey: 'creatorName',
    addKey: {
      label: {
        getLable: 'deptName',
        subLable: 'deptName',
      },
      value: {
        getLable: 'deptId',
        subLable: 'deptId',
      },
    }, // 附带值,下拉选之后,其他内容默认展示
    type: 'selectRemote',
    apiUrl: 'getStaffList',
    isFilterable: true,
    isRemote: true,
    loading: false,
    disabled: true,
    optionList: [],
    class: 'hasAddKey',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '日期',
    key: 'createTime',
    type: 'input',
    disabled: true,
    loading: false,
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '联系电话',
    key: 'contactNumber',
    type: 'input',
    disabled: true,
    loading: false,
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '类别',
    key: 'superviseCategory',
    labelKey: 'superviseCategoryName',
    type: 'select',
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '来源',
    key: 'superviseSource',
    labelKey: 'superviseSourceName',
    type: 'select',
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '签发人',
    key: 'signerId',
    labelKey: 'signerName', // 需要给后台同时传label 和 value 2个值
    type: 'selectRemote',
    apiUrl: 'getUserLeader',
    defaultValue: 'gyh',
    defaultLabelValue: '',
    isFilterable: true,
    isRemote: true,
    loading: false,
    optionList: [{
      deptId: '2',
      deptName: '公司领导',
      loginId: '',
      userName: '',
      workCode: 'CT00142',
    }],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '反馈周期',
    key: 'feedbackPeriod',
    defaultValue: 'week',
    type: 'select',
    loading: false,
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '计划办结时限',
    key: 'planFinishDate',
    type: 'date',
    optionList: [],
    class: '',
    xl: 6,
    lg: 8,
    md: 12,
    sm: 12,
  },
  {
    label: '要求',
    key: 'superviseRequirements',
    type: 'textarea',
    optionList: [],
    class: '',
    xl: 24,
    lg: 24,
    md: 24,
    sm: 24,
  },
  {
    label: '备注',
    key: 'remark',
    type: 'textarea',
    notRequired: true,
    optionList: [],
    class: '',
    xl: 24,
    lg: 24,
    md: 24,
    sm: 24,
  },
  {
    label: '附件',
    key: 'attachmentList',
    type: 'uploadFile',
    isMultiple: true,
    loading: false,
    notRequired: true,
    optionList: [],
    class: '',
    xl: 24,
    lg: 24,
    md: 24,
    sm: 24,
  },
];
<template>
  <el-form
    class="supervise-detail__form"
    ref="baseForm"
    :rules="baseRules"
    :model="baseForm"
    label-position="top"
  >
    <el-row :gutter="32">
      <el-col
        v-for="item in baseFormList"
        :key="item.key"
        :xl="item.xl"
        :lg="item.lg"
        :md="item.md"
        :sm="item.sm"
      >
        <el-form-item v-if="!item.notShow" :class="item.class" :prop="item.key">
          <template slot="label">
            {{ item.label }}
            <!-- 提示 -->
            <el-popover
              v-if="item.tipsType"
              popper-class="supervise-detail__tips"
              placement="bottom"
              trigger="hover"
            >
              <div v-if="item.tipsType === 'text'" style="max-width: 600px">
                {{ item.tips }}
              </div>
              <div v-else-if="item.tipsType === 'table'" style="max-width: 600px">
                <el-table
                  stripe
                  tooltip-effect="light"
                  :cell-style="getCellStyle"
                  :data="baseForm[item.tipsKey]"
                  style="width: 100%;">
                  <el-table-column
                    show-overflow-tooltip
                    v-for="tableItem in item.tipsHeader"
                    :key="tableItem.key"
                    :prop="tableItem.key"
                    :label="tableItem.label"
                    :width="tableItem.width || 'auto'"
                    :align="tableItem.algin || 'left'"
                  >
                    <template slot-scope="scope">
                      {{ scope.row[tableItem.key] }}
                    </template>
                  </el-table-column>
                </el-table>
              </div>
              <svg-icon
                style="margin-left: 5px;"
                slot="reference"
                class="icon"
                icon-class="infoTips"
              />
            </el-popover>
          </template>
          <!-- 输入框 -->
          <el-input
            :disabled="item.disabled ? true : false"
            v-emoji
            :maxlength="item.maxLength || 500"
            v-if="item.type === 'input'"
            v-model.trim="baseForm[item.key]"
            :placeholder="`请输入${item.label}`"
          >
          </el-input>
          <!-- 下拉选 -->
          <el-select
            :disabled="item.disabled ? true : false"
            v-else-if="item.type === 'select'"
            v-model="baseForm[item.key]"
            :filterable="item.isFilterable"
            :multiple="item.isMultiple"
            :placeholder="`请选择${item.label}`"
            collapse-tags
            @change="(val) => changeSelect(val, item, baseForm)"
          >
            <el-option
              v-for="optionItem in item.optionList"
              :key="optionItem.value"
              :label="optionItem.label"
              :value="optionItem.value"
            ></el-option>
          </el-select>
          <!-- 远程选择(员工) -->
          <el-select
            :disabled="item.disabled ? true : false"
            v-else-if="item.type === 'selectRemote'"
            v-model="baseForm[item.key]"
            :filterable="item.isFilterable"
            :remote="item.isRemote"
            :multiple="item.isMultiple"
            :placeholder="`请输入${item.label}`"
            :remote-method="(query) => getRemoteOption(query, item)"
            :loading="item.loading"
            @focus="getRemoteOption('', item)"
            @change="(str) => changeUserSelect(str, item, baseForm)"
          >
            <div slot="prefix">
              <i class="el-icon-search"></i>
            </div>
            <el-option
              v-for="optionItem in item.optionList"
              :key="optionItem.loginId"
              :label="optionItem.userName"
              :value="optionItem.loginId"
            >
              {{ `${optionItem.userName} - ${optionItem.workCode}` }}
            </el-option>
          </el-select>
          <el-input
            v-emoji
            disabled
            class="addKey"
            :maxlength="item.maxLength || 500"
            v-if="item.addKey"
            v-model.trim="baseForm[item.addKey.label.subLable]"
          >
          </el-input>
          <!-- 时间选择 -->
          <el-date-picker
            :disabled="item.disabled ? true : false"
            v-else-if="item.type === 'date'"
            v-model="baseForm[item.key]"
            type="date"
            :editable="false"
            :clearable="false"
            value-format="yyyy-MM-dd"
            :placeholder="`请选择${item.label}`"
          >
          </el-date-picker>
          <!-- 级联 -->
          <el-cascader
            :disabled="item.disabled ? true : false"
            v-else-if="item.type === 'cascader'"
            :props="{
              checkStrictly: item.isCheckStrictly,
              multiple: item.isMultiple,
            }"
            collapse-tags
            v-model="baseForm[item.key]"
            :options="item.optionList"
            @change="(val) => changeDepSelect(val, item, baseForm)"
            :placeholder="`请选择${item.label}`"
          >
          </el-cascader>
          <!-- 文本域 -->
          <el-input
            :disabled="item.disabled ? true : false"
            :maxlength="item.maxLength || 500"
            show-word-limit
            v-emoji
            v-else-if="item.type === 'textarea'"
            type="textarea"
            :rows="2"
            :autosize="{
              minRows: 3,
            }"
            v-model.trim="baseForm[item.key]"
            :placeholder="`请输入${item.label}`"
          >
          </el-input>
          <!-- 附件上传 -->
          <el-upload
            :class="{hideBtn: item.hideBtn}"
            v-else-if="item.type === 'uploadFile'"
            class="upload"
            accept="*"
            :disabled="item.disabled || uploading"
            :action="uploadUrl"
            :file-list="baseForm[item.key]"
            :before-upload="fileBeforeUpload"
            :on-preview="downloadFile"
            :on-error="uploadError"
            :on-progress="uploadProgress"
            :on-remove="(file)=>fileRemove(file, item)"
            :on-success="(res) => uploadSuccess(res, item)"
          >
            <el-button type="primary" :disabled="uploading">
              上传附件
            </el-button>
            <div slot="tip" class="el-upload__tip">
              仅支持上传以下类型文件: .pdf,.xls,.xlsx,.doc,.docx,.zip,.png,.jpg,.jpeg,.rar,且单个文件不超过50MB
            </div>
          </el-upload>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
// import { api } from '@/api';
import { flat } from '@/util/validate';
import myForm from '@/mixins/my-form';

export default {
  name: 'my-form',
  mixins: [myForm],
  components: {},
  props: {
    // 输入框类型
    baseFormList: {
      type: Array,
      default: () => [],
    },
    // 输入框选中后的传参
    baseForm: {
      type: Object,
      default: () => {},
    },
  },
  watch: {
    baseForm: {
      handler(val) {
        console.log('查看baseForm', val);
        if (val) {
          this.updateForm();
        }
      },
      deep: true,
    },
    baseFormList: {
      handler(val) {
        console.log('myfrom的表单数据baseFormList', val);
      },
      deep: true,
    },
  },
  data() {
    return {
      // 督办立项单
      baseRules: {},
      // 扁平化部门
      depOptions: [],
      // 附件上传地址
      uploadUrl: `${process.env.VUE_APP_BASE_URL}common/file/upload`,
      uploading: false,
    };
  },
  created() {
    this.initData();
    this.initOption();
  },
  methods: {
    ...mapActions(['apiGetDepList']),
    // 更新数据
    updateForm() {
      // 关闭数据后更新依然要刷新下拉框
      this.initOption();
      this.$emit('update:baseForm', this.baseForm);
    },
    // 取消校验
    closeBaseForm() {
      this.$refs.baseForm.resetFields();
    },
    // 校验必填项
    checkValidate() {
      const that = this;
      console.log(this.baseFormList, this.baseForm);
      return new Promise((resolve) => {
        this.$refs.baseForm.validate((valid) => {
          if (!valid) {
            resolve(false);
            return false;
          }
          that.updateForm();
          resolve(true);
          return true;
        });
      });
    },
    // 重置数据
    resetForm() {
      this.$refs.baseForm.resetFields();
    },
    /**
     * 附件相关
     */
    // 上传校验
    fileBeforeUpload(file) {
      const isLt50M = file.size / 1024 / 1024 < 50;
      if (!isLt50M) {
        this.$message.error('上传文件大小不能超过 50MB!');
        return false;
      }
      const suffix = file.name.split('.').slice(-1)[0].toLowerCase();
      const types = ['pdf', 'xls', 'xlsx', 'doc', 'docx', 'zip', 'png', 'jpg', 'jpeg', 'rar'];
      const isRightType = types.includes(suffix);
      if (!isRightType) {
        this.$message.error('仅支持上传以下类型文件:.pdf|.xls|.xlsx|.doc|.docx|.zip|.png|.jpg|.jpeg|.rar');
        return false;
      }
      return isLt50M && isRightType;
    },
    // 移除文件
    fileRemove(file, item) {
      this.baseForm[item.key] = this.baseForm[item.key].filter(
        (el) => (el.url !== file.url),
      );
    },
    // 上传中
    uploadProgress() {
      this.uploading = true;
    },
    // 上传失败
    uploadError(res) {
      this.$message.error(res.message);
    },
    // 上传成功
    uploadSuccess(res, item) {
      this.uploading = false;
      if (res.messageCode === '200') {
        this.baseForm[item.key].push({
          name: res.data.docName,
          ...res.data,
        });
        this.$message({
          message: '上传成功',
          type: 'success',
        });
      } else {
        this.$message({
          message: res.message,
          type: 'error',
        });
      }
    },
    // 下载文件
    downloadFile(file) {
      if (file.url) {
        const link = document.createElement('a');
        link.style.display = 'none';
        link.href = file.location;
        link.setAttribute('download', file.name);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    },
    // 数据初始化
    initData() {
      // console.log(this.baseForm, this.baseFormList);
      // 督办立项单
      this.baseFormList.forEach((el) => {
        if (el.isMultiple && !el.labelKey) {
          this.$set(this.baseForm, el.key, []);
        } else if (!el.isMultiple && el.labelKey) {
          this.$set(this.baseForm, el.key, '');
          this.$set(this.baseForm, el.labelKey, '');
        } else if (!el.isMultiple && !el.labelKey) {
          this.$set(this.baseForm, el.key, '');
        }
        if (el.defaultValue) {
          this.$set(this.baseForm, el.key, el.defaultValue);
        }
        if (el.defaultLabelValue) {
          this.$set(this.baseForm, el.labelKey, el.defaultLabelValue);
        }
        if (el.notRequired) {
          return false;
        }
        const rules = [];
        const inputType = ['input', 'textarea'];
        if (inputType.indexOf(el.type) > -1) {
          rules.push({
            required: true,
            message: `请输入${el.label}`,
            trigger: ['change', 'blur'],
          });
          this.$set(this.baseRules, el.key, rules);
        } else {
          rules.push({
            required: true,
            message: `请选择${el.label}`,
            trigger: ['change'],
          });
          this.$set(this.baseRules, el.key, rules);
        }
        return true;
      });
      // console.log(this.baseForm, this.taskInfo, this.baseRules);
    },
    // 下拉选初始化
    async initOption() {
      // 部门处理
      const res = await this.apiGetDepList();
      // 部门扁平化处理,方便获取名称
      this.depOptions = flat(res);
      // 部门相关下拉选,在这里可以更改下拉框的重置参数
      const dep = ['hostUnitId', 'assistanceUnitId', 'hostUnitName', 'assistanceUnitName'];
      this.baseFormList.forEach((el) => {
        if (this.getConditionObj[el.key]) {
          this.$set(el, 'optionList', this.getConditionObj[el.key]);
        }
        if (dep.indexOf(el.key) > -1) {
          this.$set(el, 'optionList', res[0].children);
        }
      });
    },
  },
  computed: {
    ...mapGetters(['getConditionObj', 'getUserInfo']),
  },
};
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值