element form表单封装

组件封装form表单

<template>
  <div class="search_input">
    <el-form
      :size="size"
      inline
      :model="searchData"
      :rules="rules"
      ref="searchForm"
      :label-width="labelWidth"
    >
      <el-form-item
        v-for="item in searchForm"
        :label="item.label"
        :key="item.prop"
        :prop="item.prop"
        :style="item.style"
      >
        <!-- 输入框 -->
        <el-input
          v-if="item.type === 'Input'"
          class="form_input"
          v-model="searchData[item.prop]"
          :placeholder="item.placeholder"
        ></el-input>

        <!-- 密码框 -->
        <el-input
          v-if="item.type === 'password'"
          disabled
          v-model="searchData[item.prop]"
          :placeholder="item.placeholder"
          auto-complete="off"
        >
          <template slot="append">
            <span @click="item.onClick">{{ item.name }}</span>
          </template>
        </el-input>

        <!-- 下拉框 -->
        <!-- $forceUpdate() 下拉刷新,修复数据改变下拉框不变的bug -->
        <el-select
          v-if="item.type === 'Select'"
          v-model="searchData[item.prop]"
          @change="item.change(searchData[item.prop])"
          :placeholder="item.placeholder"
          @visible-change="$forceUpdate()"
        >
          <el-option
            v-for="op in item.options"
            :label="op.label"
            :value="op.value"
            :key="op.value"
          >{{ op.label }}</el-option>
        </el-select>

        <!-- 单选 -->
        <el-radio-group
          v-if="item.type === 'Radio'"
          v-model="searchData[item.prop]"
        >
          <el-radio
            v-for="ra in item.radios"
            :label="ra.value"
            :key="ra.value"
          >{{ ra.label }}</el-radio>
        </el-radio-group>

        <!-- 组合单选按钮 -->
        <el-radio-group
          v-if="item.type === 'RadioButton'"
          v-model="searchData[item.prop]"
          @change="item.change && item.change(searchData[item.prop])"
        >
          <el-radio-button
            v-for="ra in item.radios"
            :label="ra.value"
            :key="ra.value"
          >{{ ra.label }}</el-radio-button>
        </el-radio-group>

        <!-- 复选框 -->
        <el-checkbox-group
          v-if="item.type === 'Checkbox'"
          v-model="searchData[item.prop]"
        >
          <el-checkbox
            v-for="ch in item.checkboxs"
            :label="ch.value"
            :key="ch.value"
          >{{ ch.label }}</el-checkbox>
        </el-checkbox-group>

        <!-- 日期 -->
        <el-date-picker
          v-if="item.type === 'Date'"
          v-model="searchData[item.prop]"
          value-format="yyyy-MM-dd"
          @change="item.change(searchData[item.prop])"
          :placeholder="item.placeholder"
        >
        </el-date-picker>

        <!-- 时间 -->
        <el-time-select
          v-if="item.type === 'Time'"
          v-model="searchData[item.prop]"
        >
        </el-time-select>

        <!-- 日期时间 -->
        <el-date-picker
          v-if="item.type === 'DateTime'"
          type="datetime"
          v-model="searchData[item.prop]"
          :placeholder="item.placeholder"
          value-format="yyyy-MM-dd hh:mm:ss"
          :disabled="item.disable && item.disable(searchData[item.prop])"
          @change="item.change(searchData[item.prop])"
        >
        </el-date-picker>

        <!-- 起止时间 -->
        <el-date-picker
          v-if="item.type === 'Daterange'"
          v-model="searchData[item.prop]"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          value-format="yyyy-MM-dd"
          @change="item.change(searchData[item.prop])"
        >
        </el-date-picker>
        <!-- 起止时间 -- 双picker -->
        <template v-if="item.type === 'doubleDate'">
          <el-date-picker
            v-model="searchData[item.propStart]"
            value-format="yyyy-MM-dd"
            :picker-options="item.pickerBeginDateBefore"
            @change="item.change(searchData[item.propStart])"
            :placeholder="item.placeholder"
          >
          </el-date-picker>
          <span> 到 </span>
          <el-date-picker
            v-model="searchData[item.propEnd]"
            value-format="yyyy-MM-dd"
            :picker-options="item.pickerBeginDateAfter"
            @change="item.change(searchData[item.propEnd])"
            :placeholder="item.placeholder"
          >
          </el-date-picker>
        </template>

        <!-- 滑块 -->
        <el-slider
          v-if="item.type === 'Slider'"
          v-model="searchData[item.prop]"
        >
        </el-slider>

        <!-- 开关 -->
        <el-switch
          v-if="item.type === 'Switch'"
          v-model="searchData[item.prop]"
        >
        </el-switch>

        <!-- 三级联动 cascader -->
        <el-cascader
          v-if="item.type === 'cascader'"
          :options="item.props.options"
          v-model="searchData[item.prop]"
          :placeholder="item.props.placeholder || '请选择'"
          :disabled="item.props.disabled || false"
          :props="item.props.defaultParams"
          @change="item.change(searchData[item.prop], item)"
        >
        </el-cascader>
      </el-form-item>
      <!-- button 操作按钮 -->
      <el-form-item
        class="search_input_button"
        v-if="isHandle"
      >
        <el-button
          v-for="item in searchHandle"
          :key="item.label"
          :type="item.type"
          @click="item.handle()"
        >
          <template v-if="!item.hide">
            <span>{{ item.label }}</span>
          </template>

        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  props: {
    isHandle: {
      type: Boolean,
      default: true
    },
    labelWidth: {
      type: String,
      default: "120px"
    },
    size: {
      type: String,
      default: "medium"
    },
    searchForm: {
      type: Array,
      default: () => []
    },
    searchHandle: {
      type: Array,
      default: () => []
    },
    searchData: {
      type: Object,
      default: () => { }
    }
  },
  computed: {
    // 解析表单的正则验证
    rules () {
      let rules = this.searchForm.reduce((map, i) => {
        if (i.rules) {
          map[i.prop] = i.rules;
        }
        return map;
      }, {});
      return rules;
    }
  },
}
</script>

引用组件

<template>
    <div class="baseInfo">
      <form-submit class="searchInput"
                            labelWidth="100px"
                            ref="searchForm"
                           :searchData="searchData"
                           :searchForm="searchForm" />
   </div>
</template>
<script>
import form-submit from "@/components/common/form-submit";
export default {
  components: {
    form-submit
  },
  data() {
    let caseState = [
      { label: "男", value: 1 },
      { label: "女", value: 2 }
    ];
    let entrustProps = { label: "label", value: "value" };
    let checkPhone = (rule, value, callback) => {
      if (!value) {
        return callback(new Error("手机号不能为空"));
      } else {
        const reg = /^1[3|4|5|7|8][0-9]\d{8}$/;
        if (reg.test(value)) {
          callback();
        } else {
          return callback(new Error("请输入正确的手机号"));
        }
      }
    };
    return {
      // 如果数据要回显后不可编辑,使用JSON.parse(JSON.stringify())转换
      searchData: {},
      searchForm: [
        {
          type: "Input",
          label: "人员姓名",
          prop: "name",
          width: "180px",
          placeholder: "请输入",
          // 表单验证
          rules: [{ required: true, message: "请输入活动名称", trigger: "blur" }]
        },
        {
          type: "Input",
          label: "手机号",
          prop: "phone",
          width: "180px",
          placeholder: "请输入",
          rules: [{ required: true, validator: checkPhone, trigger: "blur" }]
        },

        {
          type: "Select",
          label: "性别",
          prop: "sex",
          // 渲染数组
          options: caseState,
          // 下拉转换
          props: entrustProps,
          change: row => "",
          placeholder: "请选择性别",
          rules: [{ required: true, message: "请选择性别", trigger: "change" }]
        },
        {
          type: "Select",
          label: "所属公司",
          prop: "companyId",
          options: [],
          props: entrustProps,
          change: row => {
            this.changeCompany(row);
          },
          placeholder: "请选择所属公司",
          rules: [{ required: true, message: "请选择所属公司", trigger: "change" }]
        },
        {
          type: "Select",
          label: "所属部门",
          prop: "deptId",
          options: [],
          props: entrustProps,
          change: row => {
            this.changeDepar(row);
          },
          placeholder: "请选择所属部门",
          rules: [{ required: true, message: "请选择所属部门", trigger: "change" }]
        },
        {
          type: "Select",
          label: "当前职务",
          prop: "postId",
          options: [],
          props: entrustProps,
          change: row => {
            this.changePosition(row);
          },
          placeholder: "请选择当前职务",
          rules: [{ required: true, message: "请选择当前职务", trigger: "change" }]
        }
      ],
      ruleForm: {}
    };
  },
  methods: {
    // 下拉选择分公司,查询部门数据
    changeCompany(row) {
    },
    // 下拉选择部门,查询职位数据
    changeDepar(row) {
    },
    // 职位下拉事件
    changePosition(row) {
    }
  }
};
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容