vue js element-ui el-form表单封装 二次封装

这是一个封装了表单组件的思想。它使用了Vue.js框架和Element UI库来创建可复用的表单组件。该组件接受props作为输入,包括表单的各种配置项和数据。根据配置项的不同,组件内部会生成对应的表单元素,如输入框、下拉框、单选框、复选框等。同时,组件还提供了上传附件和预览功能。

该封装思想的优点在于可以减少代码的冗余,提高代码的复用性和维护性。通过将表单的配置项和数据作为props进行输入,可以在使用组件的地方轻松定制表单的样式和行为,同时也可以方便地对表单的数据进行处理和提交。

总体来说,该封装思想利用了Vue.js的组件化和响应式原理,使得表单的开发和使用更加简洁高效。 新增 编辑 详细 通用    废话不多说直接上代码  

form组件
<!-- Dom模板 -->
<template>
  <div>
    <!-- Dom内容 -->
    <el-form
      :model="ruleForm"
      ref="ruleForm"
      :label-width="labelWidth"
      class="el-row demo-ruleForm"
      :label-position="labelPosition"
    >
      <el-form-item
        v-for="(item, index) in formList"
        :key="index"
        :label="item.label"
        :prop="item.field"
        :rules="detail ? false : item.rules"
        :class="item.colWidth"
      >
        <!-- 输入框 -->
        <template v-if="item.type === 'input'">
          <el-input
            :placeholder="item.placeholder"
            clearable
            :disabled="disabled"
            v-model="ruleForm[`${item.field}`]"
          />
        </template>
        <!-- 下拉框 -->
        <template v-if="item.type === 'select'">
          <el-select
            v-model="ruleForm[`${item.field}`]"
            :placeholder="item.placeholder"
            :disabled="disabled"
            :multiple="item.multiple"
            style="width: 100%"
            @change="changeSelect"
          >
            <el-option
              v-for="(element, i) in item.options"
              :label="element.label"
              :value="`${element.value}`"
              :key="i"
            />
          </el-select>
        </template>
        <!-- 单选框 -->
        <template v-if="item.type === 'radio'">
          <el-radio-group
            v-model="ruleForm[`${item.field}`]"
            :disabled="disabled"
          >
            <el-radio
              v-for="(element, i) in item.options"
              :key="i"
              :label="`${element.value}`"
            >
              {{ element.label }}
            </el-radio>
          </el-radio-group>
        </template>
        <!-- 复选框 -->
        <template v-if="item.type === 'checkbox'">
          <el-checkbox-group
            v-model="ruleForm[`${item.field}`]"
            :disabled="disabled"
          >
            <el-checkbox
              v-for="(city, i) in item.cities"
              :label="city"
              :name="city"
              :key="i"
            >
              {{ city }}
            </el-checkbox>
          </el-checkbox-group>
        </template>
        <!--文本框  -->
        <template v-if="item.type === 'textarea'">
          <el-input
            :maxlength="item.maxLenght"
            type="textarea"
            :rows="item.rowsHeight"
            :disabled="disabled"
            :placeholder="item.placeholder"
            v-model="ruleForm[`${item.field}`]"
          />
        </template>
        <!-- 时间选择 -->
        <template v-if="item.type === 'date'">
          <el-date-picker
            v-model="ruleForm[`${item.field}`]"
            align="right"
            style="width: 100%"
            value-format="yyyy-MM-dd HH:mm:ss"
            :disabled="disabled"
            type="date"
            placeholder="选择日期"
            :picker-options="item.pickerOptions"
          >
          </el-date-picker>
        </template>
        <!-- 附件 -->
        <template v-if="item.type === 'upload'">
          <el-upload
            :action="item.action"
            list-type="picture-card"
            :headers="item.headers"
            :disabled="disabled"
            class="upload-demo"
            :multiple="item.multiple"
            :data="ruleForm[`${item.field}`]"
            :file-list="ruleForm[`${item.field}`]"
            :on-change="uploadFile"
            :auto-upload="false"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemove"
          >
            <i slot="default" class="el-icon-plus"></i>
          </el-upload>
        </template>
      </el-form-item>
    </el-form>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>
<script>
export default {
  props: {
    detail: {
      type: Boolean,
      default: () => false,
    },
    disabled: {
      type: Boolean,
      default: () => false,
    },
    //回显数据
    fromItem: {
      type: Object,
      default: () => null,
    },
    labelWidth: {
      type: String,
      default: () => "100px",
    },
    // 表单数据
    formNewList: {
      type: Array,
      default: () => [],
    },
    labelPosition: {
      type: String,
      default: () => "right",
    },
  },
  watch: {
    formNewList: {
      immediate: true, // 立即触发监听函数
      handler() {
        this.formList = this.formNewList;
        this.defaultFun();
      },
    },
  },
  data() {
    return {
      ruleForm: {},
      formList: [],
      dialogImageUrl: "",
      dialogVisible: false,
    };
  },
  methods: {
    //下拉框下拉事件
    changeSelect(row) {
      // console.log(row);
      this.$emit("changeSelect", row);
    },
    //上传附件
    uploadFile(file, fileList) {
      this.formList.forEach((item) => {
        if (item.type === "upload") {
          this.$set(this.ruleForm, item.field, fileList);
        }
      });
    },
    //删除附件
    handleRemove(file) {
      this.formList.forEach((item) => {
        let fileList = this.ruleForm[`${item.field}`];
        if (item.type === "upload") {
          fileList.forEach((element, i) => {
            if (file.uid === element.uid) {
              fileList.splice(i, 1);
            }
          });
        }
        this.$set(this.ruleForm, item.field, fileList);
      });
    },
    //附件预览
    handlePictureCardPreview(file) {
      console.log(file);
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    //表单默认状态
    defaultFun() {
      if (this.fromItem !== null) {
        // 数据回显
        this.ruleForm = { ...this.ruleForm, ...this.fromItem };
      } else {
        //设置默认值
        this.formList.forEach((item) => {
          if (item.cities) {
            this.$set(this.ruleForm, item.field, []);
          } else {
            this.$set(this.ruleForm, item.field, "");
          }
          if (item.type === "radio") {
            this.$set(this.ruleForm, item.field, "1");
          }
          if (item.type === "upload") {
            this.$set(this.ruleForm, item.field, []);
          }
        });
      }
      console.log(this.ruleForm);
    },
    //from表单点击事件
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$emit("headdenForm", this.ruleForm);
        }
      });
    },
    //清空表单
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

//引用

<!--index-->
<template>
  <div ref="ScaleBox" class="ScaleBox">
     <!-- Form  组件-->
     <Form
        @headdenForm="headdenForm"
        :fromItem="fromItem"
        @changeSelect="changeSelect"
        :formNewList="formList"
        :detail="edit"
        :disabled="edit"
        ref="VabForm"
      />
    <div class="cardfooter">
      <el-button @click="cancellation">取消</el-button>
      <el-button @click="save" type="primary">保存</el-button>
    </div>
  </div>
</template>
<script>
// import a from './a'; // 引入组件
import { rules } from "./view/vabForm.js";
// import {addFun} from 'cli-data'
export default {
  name: "",
  components: {
    // eslint-disable-next-line vue/no-unused-components
    rules,
  },
  data() {
    return {
      msg: "测试",
      title: "相关附件",
      edit: false,
      action: true,
      header: false,
      width: 1920,
      height: 1080,
      dataList: [
        { name: "张三", age: 19, id: 1 },
        { name: "李四", age: 20, id: 2 },
      ],
      formList: [],
      // 模拟数据 详细 测试
      fromItem: {
        id: "Shanghai",
        id1: "选项4",
        name: "用户名",
        radioId: "2",
        checkboxId: ["上海", "北京"],
        textareaIner: "textarea",
        dateTime: "2023-09-12 00:00:00",
        uploadList: [
          {
            name: "小梨猫.jpg",
            size: 160517,
            uid: 1695291434025,
            url: "https://ts1.cn.mm.bing.net/th?id=OIP-C.Zte3ljd4g6kqrWWyg-8fhAHaEo&w=316&h=197&c=8&rs=1&qlt=90&o=6&dpr=1.5&pid=3.1&rm=2",
          },
        ],
      },
      optionss: [
        {
          value: "选项1",
          label: "黄金糕",
        },
        {
          value: "选项2",
          label: "双皮奶",
        },
        {
          value: "选项3",
          label: "蚵仔煎",
        },
        {
          value: "选项4",
          label: "龙须面",
        },
        {
          value: "选项5",
          label: "北京烤鸭",
        },
      ],
      cities: [
        {
          value: "Beijing",
          label: "北京",
        },
        {
          value: "Shanghai",
          label: "上海",
        },
        {
          value: "Nanjing",
          label: "南京",
        },
        {
          value: "Chengdu",
          label: "成都",
        },
        {
          value: "Shenzhen",
          label: "深圳",
        },
        {
          value: "Guangzhou",
          label: "广州",
        },
      ],
    };
  },
  // 生命周期 - 创建完成(访问当前this实例)
  created() {},
  // 生命周期 - 挂载完成(访问DOM元素)
  mounted() {
    this.getList();
  },
  methods: {
    getList() {
      const dataList = rules();
      dataList.forEach((item) => {
        if (item.field === "id") {
          item.options = this.cities;
        }
        if (item.field === "id1") {
          item.options = this.optionss;
        }
      });
      this.formList = dataList;
    },
    //下拉框下拉事件
    changeSelect(element) {
      console.log(element);
    },
    //按钮列点击方法
    headelActionShow(element) {
      console.log(element);
    },
    //获取form 对象
    headdenForm(element) {
      console.log(element);
    },
    //保存
    save() {
      this.$refs.VabForm.submitForm("ruleForm");
    },
    //取消
    cancellation() {
      this.$refs.VabForm.resetForm("ruleForm");
    },
  },
};
</script>

<style scoped>
/* @import url(''); 引入css类  */
.ScaleBox {
  /* position: absolute; */
  /* top: 50%; */
  /* left: 50%; */
  z-index: 999;
  /* width: 1820px; */
  width: 100%;
  /* height: 1080px; */
  background-size: 100% 100%;
  -ms-transition: 0.3s;
  transition: 0.3s;
  /* transform: scale(var(--scale)) translate(-50%, -50%); */
  -ms-transform-origin: 0 0;
  transform-origin: 0 0;
}
.cardfooter {
  width: 100%;
  /* padding: 20px; */
  position: fixed;
  bottom: 20px;
  right: 30px;
  text-align: right;
  /* background: ; */
}
</style>

vabForm.js

export const rules = () => {
  return [
    {
      field: 'id',
      type: 'select',
      label: '部门',
      multiple:false,
      placeholder: '请选择部门',
      colWidth: 'el-col-10',
      options: [
        {
          label: '部门一',
          value: 90000,
        },
        {
          label: '部门二',
          value: 50000,
        }
      ],
      rules: [
        {
          required: true,
          message: '请选择部门',
          trigger: 'change'
        },
      ]
    },
    {
      field: 'id1',
      type: 'select',
      label: '部门1',
      multiple:false,
      placeholder: '请选择部门1',
      colWidth: 'el-col-10',
      options: [
        {
          label: '部门一1',
          value: 2345678,
        },
        {
          label: '部门二2',
          value: 6543450,
        }
      ],
      rules: [
        {
          required: true,
          message: '请选择部门',
          trigger: 'change'
        },
      ]
    },
    {
      field: 'name',
      label: '用户名',
      placeholder: '请输入活动名称',
      type: 'input',
      maxLenght: 20,
      colWidth: 'el-col-24',
      rules: [
        { required: true, message: '请输入活动名称', trigger: ['blur', 'change'] },
      ]
    },
    {
      field: 'radioId',
      type: 'radio',
      label: '备选项',
      colWidth: 'el-col-24',
      options: [
        {
          label: '选项一',
          value: '1',
        },
        {
          label: '选项二',
          value: '2',
        }
      ],
      rules: [
        {
          required: true,
          message: '请选择备选项',
          trigger: 'blur'
        },
      ]
    },
    {
      field: 'checkboxId',
      type: 'checkbox',
      label: '状态',
      colWidth: 'el-col-24',
      cities: ['上海', '北京', '广州', '深圳'],
      rules: [
        {
          required: true,
          message: '请选择状态',
          trigger: 'change'
        },
      ]
    },

    {
      field: 'textareaIner',
      label: '内容',
      placeholder: '请输入内容',
      maxLenght: 300,
      type: 'textarea',
      rowsHeight: 4,
      colWidth: 'el-col-24',
      rules: [
        { required: true, message: '请输入内容', trigger: ['blur', 'change'] }
      ]
    },
    {
      field: 'dateTime',
      label: '内容',
      placeholder: '请输入内容',
      type: 'date',
      pickerOptions: pickerOptions(),
      colWidth: 'el-col-24',
      rules: [
        { required: true, message: '请输入内容', trigger: 'blur' }
      ]
    },
    {
      field: 'uploadList',
      label: '附件',
      headers: {},
      action: '/action',
      type: 'upload',
      multiple: true,
      colWidth: 'el-col-24',
      rules: [
        { required: true, message: '请上传附件', trigger: ['blur', 'change'] },
        callback()
      ]
    },
  ]
}

function callback() {
  return {
    validator: function (rule, value, callback) {
      console.log(rule, value);
      if (value) {
        callback()
      }
    }
  }
}
function pickerOptions() {
  return {
    disabledDate(time) {
      return time.getTime() > Date.now();
    },
    shortcuts: [{
      text: '今天',
      onClick(picker) {
        picker.$emit('pick', new Date());
      }
    }, {
      text: '昨天',
      onClick(picker) {
        const date = new Date();
        date.setTime(date.getTime() - 3600 * 1000 * 24);
        picker.$emit('pick', date);
      }
    }, {
      text: '一周前',
      onClick(picker) {
        const date = new Date();
        date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
        picker.$emit('pick', date);
      }
    }]
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值