zoukankan      html  css  js  c++  java
  • vue element form 封装

    <template>
      <el-row :gutter="$attrs.gutter">
        {{ formData }}
        <el-form
          v-bind="$attrs"
          v-on="$listeners"
          :label-width="$attrs.labelWidth || '140px'"
        >
          <template v-for="item in formHeader">
            <el-col
              :key="item.prop"
              v-if="!item.hidden"
              :span="item.span || allSpan"
              :class="item.right ? 'flexAlignCenterRight' : ''"
            >
              <el-form-item
                v-bind="item"
                :rules="
                  item.required
                    ? [
                        {
                          required: true,
                          message: `${item.label.replace(/(.*?)/g, '')}必填`,
                          trigger: 'blur',
                        },
                      ]
                    : null
                "
                v-required="
                  item.dir === true || (item.required && item.dir !== false)
                    ? formData[item.prop]
                    : '1'
                "
              >
                <!-- 渲染函数 -->
                <template v-if="item.render">
                  <ex-slot :render="item.render" :row="formData" />
                </template>
                <!-- 上传 -->
                <template v-else-if="item.type === 'upload'">
                  <el-upload
                    ref="upload"
                    style=" 200px"
                    :file-list="field101fileList"
                    :action="field101Action"
                    :multiple="item.multiple || false"
                    :before-upload="field101BeforeUpload"
                    :accept="item.accept || '*'"
                    :disabled="item.disabled || false"
                  >
                    <el-button size="small" type="primary" icon="el-icon-upload"
                      >点击上传</el-button
                    >
                    <div slot="tip" class="el-upload__tip">
                      {{ item.upload__tip }}
                    </div>
                  </el-upload>
                </template>
                <!-- 日期范围选择器 -->
                <template v-else-if="item.type === 'daterange'">
                  <el-date-picker
                    type="daterange"
                    v-model="formData[item.prop]"
                    v-bind="item"
                    :format="item.format || 'yyyy-MM-dd'"
                    :value-format="item.valueFormat || 'yyyy-MM-dd'"
                    :start-placeholder="item.startPlaceholder || '开始日期'"
                    :end-placeholder="item.endPlaceholder || '结束日期'"
                    :range-separator="item.rangeSeparator || '至'"
                  ></el-date-picker>
                </template>
                <!-- 日期选择器 -->
                <template v-else-if="item.type === 'date'">
                  <el-date-picker
                    v-model="formData[item.prop]"
                    :format="item.format || 'yyyy-MM-dd'"
                    :value-format="item.valueFormat || 'yyyy-MM-dd'"
                    v-bind="item"
                  ></el-date-picker>
                </template>
                <!-- 时间选择器 -->
                <template v-else-if="item.type === 'timerange'">
                  <el-time-picker
                    v-model="formData[item.prop]"
                    v-bind="item"
                    is-range
                    :format="item.format || 'HH:mm:ss'"
                    :value-format="item.valueFormat || 'HH:mm:ss'"
                    :start-placeholder="item.startPlaceholder || '开始时间'"
                    :end-placeholder="item.endPlaceholder || '结束时间'"
                    :range-separator="item.rangeSeparator || '至'"
                  ></el-time-picker>
                </template>
                <!-- 时间选择器 -->
                <template v-else-if="item.type === 'time'">
                  <el-time-picker
                    v-model="formData[item.prop]"
                    :format="item.format || 'HH:mm:ss'"
                    :value-format="item.valueFormat || 'HH:mm:ss'"
                    :picker-options="{ selectableRange: '00:00:00-23:59:59' }"
                    v-bind="item"
                  ></el-time-picker>
                </template>
                <!-- 下拉 -->
                <template v-else-if="item.type === 'select'">
                  <el-select
                    v-model="formData[item.prop]"
                    v-bind="item"
                    :multiple="item.multiple || false"
                    :filterable="item.filterable || true"
                    :disabled="item.disabled || false"
                  >
                    <el-option
                      v-for="(el, i) in item.options"
                      :key="i"
                      :label="el.label"
                      :value="el.value"
                      :disabled="el.disabled"
                    >
                    </el-option>
                  </el-select>
                </template>
                <!-- 单选 -->
                <template v-else-if="item.type === 'radio'">
                  <el-radio-group
                    v-model="formData[item.prop]"
                    v-bind="item"
                    :disabled="item.disabled || false"
                  >
                    <el-radio
                      v-for="(el, i) in item.options"
                      :key="i"
                      :label="el.value"
                      :disabled="el.disabled"
                      :border="el.border"
                    >
                      {{ el.label }}
                    </el-radio>
                  </el-radio-group>
                </template>
                <!-- 滑块 -->
                <template v-else-if="item.type === 'switch'">
                  <el-switch
                    style=" 200px"
                    v-model="formData[item.prop]"
                    :active-text="item.activeText"
                    :inactive-text="item.inactiveText"
                    :active-color="item.activeColor ? item.activeColor : '#13ce66'"
                    :inactive-color="
                      item.inactiveColor ? item.inactiveColor : '#ff4949'
                    "
                    :disabled="item.disabled || false"
                  ></el-switch>
                </template>
                <!-- 多选 -->
                <template v-else-if="item.type === 'checkbox'">
                  <el-checkbox-group
                    v-model="formData[item.prop]"
                    v-bind="item"
                    :disabled="item.disabled || false"
                    :min="item.min"
                    :max="item.max"
                  >
                    <el-checkbox
                      v-for="(el, i) in item.options"
                      :key="i"
                      :label="el.value"
                      :disabled="el.disabled"
                      :border="el.border"
                    >
                      {{ el.label }}
                    </el-checkbox>
                  </el-checkbox-group>
                </template>
                <!-- 输入型 -->
                <!-- 多行 考虑加入富文本-->
                <template v-else-if="item.type === 'textarea'">
                  <el-input
                    type="textarea"
                    v-model.trim="formData[item.prop]"
                    v-bind="item"
                  >
                    <template slot="prepend" v-if="item.prepend">{{
                      item.prepend
                    }}</template>
                    <template slot="append" v-if="item.append">{{
                      item.append
                    }}</template>
                  </el-input>
                </template>
                <!-- 计数 -->
                <template
                  v-else-if="item.type === 'number' || item.type === 'price'"
                >
                  <!-- {{item}}v-model.trim="formData[item.prop]" -->
                  <!-- <el-input
                    :value="formatterValue(item)"
                    @input="change($event,item)"
                    @change="change($event,item)"
    
                  ></el-input> -->
                   <el-input-number
                  v-model.trim="formData[item.prop]"
                  :controls="item.controls || false"
                  :step="item.step || 0.01"
                  v-bind="commonProp(item)"
                  :min="
                    item.min !== null && item.min !== undefined ? item.min : 0.0
                  "
                  :precision="
                    item.precision !== null && item.precision !== undefined
                      ? item.precision
                      : 2
                  "
                  :max="
                    item.max !== null && item.max !== undefined
                      ? item.max
                      : 100000000
                  "
                  :step-strictly="item.stepStrictly || true"
                ></el-input-number>
                </template>
                <!-- 单行 -->
                <template v-else>
                  <el-input
                    v-model.trim="formData[item.prop]"
                    v-bind="item"
                    :prefix-icon="item.prefixIcon"
                    :suffix-icon="item.suffixIcon"
                    style=" 200px"
                  >
                    <template slot="prepend" v-if="item.prepend">{{
                      item.prepend
                    }}</template>
                    <template slot="append" v-if="item.append">{{
                      item.append
                    }}</template>
                  </el-input>
                </template>
              </el-form-item>
            </el-col>
          </template>
        </el-form>
      </el-row>
    </template>
    <script>
    // 自定义内容的组件
    let exSlot = {
      functional: true,
      props: {
        row: Object,
        render: Function,
      },
      render: (h, data) => {
        const params = {
          row: data.props.row,
        };
        return data.props.render(h, params);
      },
    };
    export default {
      name: "form-default",
      inheritAttrs: false,
      components: { exSlot },
      props: {
        //所有col统一栅格
        allSpan: {
          type: Number,
          default: 12,
        },
        //所有控件统一宽度
        allWidth: {
          type: [String, Number],
          default: "200px",
        },
        formData: {
          type: Object,
          default: function () {
            return {};
          },
        },
        // 表头数据
        formHeader: {
          type: Array,
          default: function () {
            return [];
          },
        },
      },
      computed: {
        // formatterValue(e) {
        //   // if (this.formatter && this.precisionValue !== null) {
        //   //   return this.formatter(this.precisionValue);
        //   // } else {
        //   //   return this.precisionValue;
        //   // }
        //   console.log(e.target);
        //   // return 55
        // },
      },
      data() {
        return {
          field101Action: "https://jsonplaceholder.typicode.com/posts/",
          field101Action: "#",
          field101fileList: [],
        };
      },
      // computed: {
      //   comHeader() {
      //     return this.formHeader;
      //   },
      // },
      created() {
        this.formHeader.forEach((item) => {
          if (
            item.format === "array" &&
            Object.prototype.toString.call(this.formData[item.prop]) !==
              "[object Array]"
          ) {
            this.$set(this.formData, item.prop, []);
          }
        });
      },
      methods: {
        formatterValue(item){
          if(item.formatter){
    return item.formatter(this.formData[item.prop])
          }else{
    return this.formData[item.prop]
          }
          // console.log(item.formatter(50000));
          // console.log(this.change);
    
          // return item.formatter(this.formData[item.prop])
        },
        change(event,item) {
          if(item.parser){
     this.formData[item.prop]=item.parser(event)
          }else{
     this.formData[item.prop]=event
          }
    
        },
        validate() {
          return this.$refs.elForm.validate();
        },
        clearValidate() {
          this.$refs.elForm.clearValidate();
        },
        proppath(row, path) {
          let arr = path.split(".");
          let a = row;
          arr.forEach((item) => {
            a = a[item];
          });
          return a;
        },
        field101BeforeUpload(file) {
          let isRightSize = file.size / 1024 / 1024 < 2;
          if (!isRightSize) {
            this.$message.error("文件大小超过 2MB");
          }
          console.log(file.type);
          let isAccept = new RegExp("application").test(file.type);
          if (isAccept) {
            this.$message.error("应该选择非.exe等类型的文件");
          }
          return isRightSize && isAccept;
        },
      },
    };
    </script>
    <style lang="scss" scoped>
    ::v-deep .el-input-number .el-input__inner {
      text-align: left;
    }
    </style>
    

      

    <template>
      <FormDefault
        :formData="info"
        :formHeader="defaultHeader"
        :rules="rules"
        class="mt10"
        ref="elForm"
        :model="info"
        size="mini"
      ></FormDefault>
    </template>
    
    <script>
    import FormDefault from "./form.vue";
    export default {
      components: { FormDefault },
      data() {
        return {
          info: {
            f1: 12,
          },
          rules: {
            f1: [{ required: true }],
          },
          defaultHeader: [
            {
              prop: "f0",
              label: "评测预算费(元)",
              placeholder: "请输5入金额",
              type: "upload",
              required: true,
              render: (h, params) => {
                return [<div>4545</div>];
              },
            },
    
            {
              prop: "f1",
              label: "评测预算费(元)",
              placeholder: "请输5入金额",
              type: "number",
              formatter: (value) =>
                `${value}`.replace(/B(?=(d{3})+(?!d))/g, ","),
              parser: (value) => `${value}`.replace(/$s?|(,*)/g, ""),
              required: true,
            },
            {
              prop: "f2",
              label: "研发预算费(元)",
              placeholder: "请输入金额",
              type: "daterange",
            },
            {
              prop: "f3",
              label: "专利预算费(元)",
              placeholder: "请输入金额",
              type: "date",
            },
            {
              prop: "f4",
              label: "专家验收预算费(元)",
              placeholder: "请输入金额",
              type: "timerange",
            },
    
            {
              prop: "f53",
              label: "采购预算费(元)",
              placeholder: "请输入金额",
              type: "time",
            },
    
            {
              prop: "f54",
              label: "实施预算费(元))",
              placeholder: "请输入金额",
              type: "select",
              multiple: true,
              options: [
                {
                  value: "选项1",
                  label: "黄金糕",
                },
                {
                  value: "选项2",
                  label: "双皮奶",
                },
                {
                  value: "选项3",
                  label: "蚵仔煎",
                },
              ],
            },
    
            {
              prop: "f5",
              label: "其他预算费(元)",
              placeholder: "请输入金额",
              type: "radio",
              options: [
                {
                  value: "选项1",
                  label: "黄金糕",
                },
                {
                  value: "选项2",
                  label: "双皮奶",
                },
                {
                  value: "选项3",
                  label: "蚵仔煎",
                },
              ],
            },
            {
              prop: "f6",
              label: "论文预算费(元)",
              placeholder: "请输入金额",
              type: "switch",
            },
            {
              prop: "f7",
              label: "论文预算费(元)",
              placeholder: "请输入金额",
              type: "checkbox",
              format: "array",
              options: [
                {
                  value: "选项1",
                  label: "黄金糕",
                },
                {
                  value: "选项2",
                  label: "双皮奶",
                },
                {
                  value: "选项3",
                  label: "蚵仔煎",
                },
              ],
            },
            {
              prop: "f8",
              label: "论文预算费(元)",
              placeholder: "请输入金额",
              type: "textarea",
            },
            {
              prop: "f9",
              label: "论文预算费(元)",
              placeholder: "请输入金额",
              type: "number",
            },
            {
              prop: "f10",
              label: "论文预算费(元)",
            },
            {
              prop: "sum",
              label: "预算总额(元)",
              placeholder: "自动计算",
              render: (h, params) => {
                return [<span>4454545</span>];
              },
            },
          ],
        };
      },
    };
    </script>
    
    <style scoped>
    </style>
    

      

  • 相关阅读:
    [管理]管理者应需要知道的一些定律
    推荐IOS Moneky测试工具Fast Monkey
    [原创]强烈推荐Cmd终极替换工具Cmder
    [原创] 2018年测试行业各职位薪水参考表
    [原创]管理者如何激励下属更有效的工作?
    [原创]SonarQube代码质量检查工具介绍
    [原创]F2etest是一个面向前端、测试、产品等岗位的多浏览器兼容性测试整体解决方案。
    [原创] IMB AppScan 9.0下载及破解
    [原创] Influxdb+Grafana+Jmeter性能监控工具搭建
    [原创]浅谈互联网金融接口测试平台搭建
  • 原文地址:https://www.cnblogs.com/7c89/p/15094620.html
Copyright © 2011-2022 走看看