form组件的封装(element ui ) 简单版本

2023-09-22 09:05:42

当你使用Vue.js构建Web应用时,封装可复用组件是提高开发效率和代码可维护性的关键之一。在这篇文章中,我们将探讨如何使用Vue.js来创建一个通用的表单组件,以及如何将它封装成一个可配置的组件。

实现思路

  • 拿下表单模板
  • 一个个的改造(文本,下拉,单选,复选等)
  • 按钮
  • 默认值的设定
  • rules规则的处理

创建通用的form组件

这段代码是一个Vue.js组件,用于创建一个动态表单。以下是对代码的简要解释:

1. 在模板部分,使用`<el-form>`创建一个表单,绑定了`ruleForm`对象作为数据模型和`rules`对象作为验证规则。
2. 使用`v-for`循环遍历`data.items`,根据每个`item`的类型创建不同的表单元素,如输入框、选择框、开关、多选框、单选框、文本域、日期选择器和时间选择器。
3. 在`<el-form-item>`内部,根据`item.type`的不同,使用Vue指令`v-if`来渲染不同的表单元素。
4. 在脚本部分,定义了一个Vue组件,接受一个`data`对象作为属性传递进来,初始化了`ruleForm`和`rules`对象。
5. 在`created`生命周期钩子中,调用`init`方法初始化表单的默认值和验证规则。
6. `init`方法根据每个`item`的类型,将默认值设置到`ruleForm`中。
7. 定义了`callSeif`方法,用于处理按钮的点击事件,包括提交表单和重置表单。
8. `submitForm`方法通过`validate`函数验证表单的有效性,如果通过验证,则执行回调函数。
9. `resetForm`方法用于重置表单,根据不同的表单元素类型清空表单字段。

这段代码用于创建一个可配置的动态表单,通过传入不同的配置数据,可以生成不同类型的表单,并在用户交互时执行相应的操作。这是一个强大的工具,可用于快速构建各种表单页面。如果需要更详细的文章,请提供具体的方向或问题。

<template>
  <el-form :model="ruleForm" :rules="rules" ref="ruleForm" :label-width="data.width">
    <el-form-item :label="item.label" :prop="item.prop" v-for="(item, k) in data.items" :key="k">
      <el-input v-if="item.type == 'Input'" v-model="ruleForm[item.prop]" :placeholder="item.placeholder"
        :style="{ width: item.width }"></el-input>
      <el-select v-model="ruleForm[item.prop]" v-if="item.type == 'Select'" :placeholder="item.placeholder"
        :style="{ width: item.width }">
        <el-option v-for="(o, i) in item.options" :label="o.label" :value="o.value" :key="i"></el-option>
      </el-select>
      <el-switch v-model="ruleForm[item.prop]" v-if="item.type == 'Switch'"></el-switch>
      <el-checkbox-group v-model="ruleForm[item.prop]" v-if="item.type == 'Checkbox'">
        <el-checkbox :label="o.value" v-for="(o, i) in item.options" :key="i">{{
          item.label
        }}</el-checkbox>
      </el-checkbox-group>
      <el-radio-group v-model="ruleForm[item.prop]" v-if="item.type == 'Radio'">
        <el-radio :label="o.value" v-for="(o, i) in item.options" :key="i">{{
          item.label
        }}</el-radio>
      </el-radio-group>
      <el-col :span="item.span || 11">
        <el-input v-if="item.type == 'Textarea'" v-model="ruleForm[item.prop]" :placeholder="item.placeholder"
          type="textarea"></el-input>
      </el-col>
      <el-col :span="item.span || 5">
        <el-date-picker type="date" style="width: 100%" v-model="ruleForm[item.prop]" :placeholder="item.placeholder"
          v-if="item.type == 'Date'"></el-date-picker></el-col>
      <el-col :span="item.span || 5">
        <el-time-picker style="width: 100%" v-model="ruleForm[item.prop]" :placeholder="item.placeholder"
          v-if="item.type == 'Time'"></el-time-picker></el-col>
      <el-col :span="item.span || 5">
        <el-date-picker type="datetime" style="width: 100%" v-model="ruleForm[item.prop]" :placeholder="item.placeholder"
          v-if="item.type == 'Datetime'"></el-date-picker></el-col>
    </el-form-item>
    <el-form-item>
      <el-button :type="b.type" @click="callSeif('ruleForm', b.action, b.call)" v-for="(b, k) in data.buttons" :key="k">{{
        b.label }}</el-button>
    </el-form-item>
  </el-form>
</template>
<script>
export default {
  props: {
    data: Object,
  },
  name: "Form",
  data() {
    return {
      ruleForm: {},
      rules: {},
    };
  },
  created() {
    this.init();
  },
  methods: {
    init() {
      let form = {};
      let box = [];
      this.data.items.forEach((item) => {
        switch (item.type) {
          case "Checkbox":
            if (item.default) {
              if (Array.isArray(item.default)) {
                box = box.concat(item.default);
              } else {
                box.push(item.default);
              }
            }
            form[item.prop] = box;
            break;
          case "Datetime":
            if (item.default) {
              form[item.prop] = new Date(item.default);
            }
            break;
          case "Time":
            if (item.default) {
              form[item.prop] = new Date(item.default);
            }
            break;
          case "Date":
            if (item.default) {
              form[item.prop] = new Date(item.default);
            }
            break;
          default:
            form[item.prop] = item.default;
            break;
        }
      });
      this.ruleForm = form;
      console.log(form);
      this.rules = this.data.rules
    },
    callSeif(formName, action, callback) {
      if (action == "submit") {
        this.submitForm(formName, callback);
      } else if (action == "reast") {
        this.resetForm(formName);
      } else {
        callback && callback();
      }
    },
    submitForm(formName, callback) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          callback && callback(this.ruleForm);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      console.log("重置",);
      let form = {};

      this.data.items.forEach((item) => {
        switch (item.type) {
          case "Checkbox":
            form[item.prop] = [];
            break;
          default:
            form[item.prop] = '';
            break;
        }
      });
      this.ruleForm = form;
      this.$refs[formName].resetFields();
      console.log(this.ruleForm);
    },
  },
};
</script>

如何使用这个组件

现在,让我们看看如何在Vue.js应用中使用这个通用的表单组件。首先,你需要导入这个组件并注册它,然后可以在模板中使用它。

<template>
  <div class="table-page">
    <Form :data="formData"></Form>
  </div>
</template>
<script>
import Form from "./componentsdemo/form.vue";
export default {
  name: "Index",
  components: {
    Form,
  },

  data() {
    return {
      formData: {
        width: "180px",
        items: [
          {
            type: "Input",
            label: "活动名称",
            prop: "name",
            width: "100px",
            placeholder: "请输入活动区域",
            default: "请",
          },
          {
            type: "Select",
            placeholder: "请选择活动区域",
            prop: "region",
            label: "活动区域",
            options: [
              {
                label: "区域一",
                value: "shanghai",
              },
              {
                label: "区域二",
                value: "beijing",
              },
            ],
            default: "shanghai",
          },
          {
            type: "Switch",
            label: "即时配送",
            prop: "delivery",
            default: true,
          },
          {
            type: "Checkbox",
            label: "活动性质",
            prop: "type",
            options: [
              {
                label: "线下主题活动",
                value: "1",
              },
              {
                label: "单纯品牌曝光",
                value: "2",
              },
            ],
            default: ["1", "2"],
          },
          {
            type: "Radio",
            label: "特殊资源",
            prop: "resource",
            options: [
              {
                label: "线下主题活动",
                value: "a",
              },
              {
                label: "单纯品牌曝光",
                value: "b",
              },
            ],
            default: 'a',
          },
          {
            type: "Textarea",
            label: "活动形式",
            prop: "desc",
            placeholder: "请输入活动形式",
            span: 10,
            default: '活动',
          },
          {
            type: "Date",
            label: "活动日期",
            prop: "data1",
            placeholder: "请输入活动日期",
            span: 10,
            default: '2023-08-21',
          },
          {
            type: "Time",
            label: "活动时间",
            prop: "data2",
            placeholder: "请输入活动时间",
            span: 10,
            default: '2023-08-21 12:00:00',
          },
          {
            type: "Datetime",
            label: "活动日期时间",
            prop: "data3",
            placeholder: "请输入活动日期时间",
            span: 10,
            default: '2023-08-21 12:00:00',
          },
        ],
        buttons: [
          {
            label: "确定",
            type: "text",
            action: "submit",
            call: (Form) => {
              console.log(Form);
            },
          },
          {
            label: "重置",
            type: "text",
            action: "reast",
            call: () => {
              console.log("reast");
            },
          },
        ],
        rules: {
          // name: [
          //   { required: true, message: "请输入活动名称", trigger: "blur" },
          //   { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
          // ],
          region: [{ required: true, message: "请选择活动区域", trigger: "change" }],
          date1: [
            { type: "date", required: true, message: "请选择日期", trigger: "change" },
          ],
          date2: [
            { type: "date", required: true, message: "请选择时间", trigger: "change" },
          ],
          type: [
            {
              type: "array",
              required: true,
              message: "请至少选择一个活动性质",
              trigger: "change",
            },
          ],
          resource: [{ required: true, message: "请选择活动资源", trigger: "change" }],
          desc: [{ required: true, message: "请填写活动形式", trigger: "blur" }],

        }
      },
    };
  },
  methods: {},
};
</script>

在上述示例中,我们首先导入了通用下拉选择框组件,然后在模板中使用它,并将需要的数据传递给它。当选择项发生变化时,我们可以通过@change事件来处理选择结果。

结语

通过封装通用组件,我们可以在Vue.js应用中轻松地实现重复使用的功能,提高开发效率并减少重复工作。通用表单组件是一个很好的例子,它可以根据不同的需求进行配置,使其适用于多种情况。希望本文对你理解如何创建和使用Vue.js组件有所帮助!
 

更多推荐

【深入浅出设计模式--命令模式】

深入浅出设计模式--命令模式一、背景二、问题三、解决方案四、试用场景总结五、后记一、背景命令模式是一种行为设计模式,它可以将用户的命令请求转化为一个包含有相关参数信息的对象,命令的发送者不需要知道接收者是如何处理这条命令,多个功能入口可以发送同一命令,避免多处多次实现相同功能的冗余代码。另外可以对命令进行延迟处理,或放

【RocketMQ】消息中间件学习笔记

【RocketMQ】消息中间件学习笔记【一】RocketMQ概述【1】MQ简介【2】MQ永用途(1)限流削峰(2)异步解耦(3)数据收集【3】RocketMQ介绍(1)RocketMQ特点(2)RocketMQ优势【4】RocketMQ基本概念(1)NameServer(2)Broker(3)生产者(Producer)

亚马逊六页纸

一、什么是亚马逊6页纸?亚马逊在内部管理实践中,特别是会议管理上,禁止使用PPT,而是使用一种简洁的「结构化备忘录」,也就是我们熟知的“六页纸”。二、具体解释1、Whatwedo?背景,什么情况下,我们做了什么。因为XXX产品即将量产,我们已启动XXX下一版升级产品的规划。今天开会的主题就是汇报与同步目前的规划情况。2

JS的WebAPI

WebAPI背景知识什么是WebAPI前面学习的JS分成三个大的部分ECMAScript:基础语法部分DOMAPI:操作页面结构BOMAPI:操作浏览器WebAPI就包含了DOM+BOM.什么是APIAPI是一个更广义的概念.而WebAPI是一个更具体的概念,特指DOM+BOM,所谓的API本质上就是一些现成的函数/对

【视觉SLAM入门】9.1 建图1---SLAM任务,稠密地图构建,立体视觉,RGBD,八叉树,点云地图等各种不同地图

"讷为君子,寡为吉人”1.立体稠密地图1.1地图构建1.2分析立体相机稠密建图效果2.RGB-D稠密地图2.1地图对比2.1.1八叉树地图3.建图?定位?孰轻孰重3.1鬼影问题3.2三维重建4.总结SLAM的功能:直到现在我们可以知道SLAM包含:定位,导航,避障,重建,交互。在不同的功能下也有不同的地图。之前的都是稠

计算机毕设 python图像检索系统设计与实现

文章目录0前言1课题简介2图像检索介绍(1)无监督图像检索(2)有监督图像检索3图像检索步骤4应用实例5最后0前言🔥这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。为了大家能够顺利以及最少的精力通过

Rockchip RK3399 - USB触摸屏接口驱动

----------------------------------------------------------------------------------------------------------------------------开发板:NanoPC-T4开发板eMMC:16GBLPDDR3:4GB显

spring:实现初始化动态bean|获取对象型数组配置文件

0.引言近期因为要完成实现中间件的工具包组件,其中涉及要读取对象型的数组配置文件,并且还要将其加载为bean,因为使用了spring4.3.25.RELEASE版本,很多springboot的相关特性无法支持,因此特此记录,以方便后续同学有相同情况可以参考1.获取对象型数组配置文件首先对象型数组配置文件如下所示:min

什么是实时操作系统(UCOS简介)

uC/OS-III官网:HomePage-WestonEmbeddedSolutions一、裸机与RTOS介绍下面我将从不同方面阐述裸机与试试操作系统的区别,从而进一步介绍裸机和实时操作系统定义:裸机:裸机指的是没有任何操作系统或软件层的硬件系统。在裸机状态下,程序可以直接访问硬件资源。实时操作系统:实时操作系统(RT

[Python进阶] 程序打包之Pyinstaller参数介绍

5.4Pyinstaller参数介绍5.4.1选项参数参数名说明-h、–help查看Pyinstaller所有命令的用法和帮助-v、–version查看当前Pyinstaller版本–distpathDIR设置dist位置,默认当前目录–workpathWORKPATH设置build位置,默认当前目录-y、–nocon

Java基础之lambda表达式(JDK1.8新特性)

文章目录Lambda表达式各种函数式接口Lambda的语法Lambda表达实例举例说明变量作用域处理lambda表达式变量作用域函数式接口使用实例1使用实例2使用示例3(集合排序)使用示例4(按照对象属性给list排序)使用示例4总结参考Lambda表达式Lambda表达式允许把函数作为一个方法的参数(函数作为参数传递

热文推荐