element适用于多个组件 input输入框组件的二次封装

3,037 阅读2分钟

element适用于多个组件 input输入框组件的二次封装.

前言

用element的时候,经常需要写多个输入框,就想把它写成一个组件,看了网上很多例子,要么不符合我的要求,要么就是太复杂,所以想自己写一个对我来说比较通俗易懂的组件。有什么不妥的地方欢迎各位大佬指正

先上图片看看效果:有时间选择器,input输入框,下拉选择和按钮组 首先 首先使用了element的el-form表单组件,model是表单的数据对象,用于双向绑定;rules是表单的验证规则,inline是行内表单模式;关于更多详细参数,可参考官网element.eleme.cn/#/zh-CN/com…

关于输入框input 循环传过来的commodityMessage数组, 之前一直肯苦恼关于v-model绑定的字段必须是唯一的怎么整,后面为了方便就想到了,把循环的每个prop的字段名称和v-model绑定的ruleForm里面的字段名称保持一致就可以了。例如在data中这样:

	ruleForm: {
        number: "", //编号
        orderNumber:"",//单号
      },
      commodityMessage: [
        {
          label: "编号",
          prop: "number",
        },
        {
          label: "单号",
          prop: "orderNumber",
          widths:'500'
        },

我们得到的结果就是这样两个输入框,

关于Select 选择器

这部分我是判断在commodityMessage的每个对象中是否存在optionSelect对象,如果存在,就是select选择器,同样的v-model绑定的值是commodityMessage每个对象的prop的字段,我们相应的也要在ruleForm添加此字段。关于选择框的值是循环对象中的optionSelect,optionSelect中的label是绑定的是选择的label文字,optionSelect中的value是绑定的是选择得到的值 例如这样:

	<el-select
          v-else-if="item.optionSelect && !item.isDate"
          v-model="ruleForm[item.prop]"
          :placeholder="item.label ? '请输入'+ item.label : ''"
          :style="item.widths ? 'width'+ item.widths +'%' : 'width:148px'"
        >
          <el-option
            v-for="ele in item.optionSelect"
            :key="ele.label"
            :label="ele.label"
            :value="ele.value"
          ></el-option>
        </el-select>
ruleForm: {
        site:"", //场地
      },
      commodityMessage: [
        {
          label: "场地",
          prop: "site",
          optionSelect: [
            {
              label: "全部",
              value: "shanghai"
            },
            {
              label: "零食区",
              value: "beijing"
            }
          ]
        },

我们得到的结果是:

关于时间选择器

我们往往可能会需要用到时间选择器,所以我在这里也简单的写了一下 使用与input框的使用方法类似,只要在commodityMessage中的对象添加isDate:true就是时间选择器

ruleForm: {
        startDate:'',
      },
      commodityMessage: [
        {
          label: "下单时间",
          prop: "startDate",
          isDate:true
        },

我们可以看下效果:

关于按钮

在输入框中大多数都会使用到一些按钮,我在这里也简单封装了一下 循环searchBtns数组,name是按钮的文字,fun是按钮的函数名,type是按钮的颜色 然后在组件中分别绑定事件,字段名就是searchBtns的fun。例如:

<el-form-item v-if="searchBtns.length > 0 ">
     <el-button size="mini" v-for="btn in searchBtns" :key="btn.name"  @click="$emit(btn.fun)" :type="btn.type ? btn.type : 'primary'">{{btn.name}}</el-button>
 </el-form-item>

使用中:

data(){
	return{
		searchBtns: [
        	{
          	name: "搜索",
          	fun:'onSearch'
        	},
        	{
          	name: "导出",
          	fun:'exportFun'
        	},
        	{
          	name: "清空搜索条件",
          	fun:'emptyFun',
          	type:'warning'
        	},
      	  ],
   	}
},
 methods: {
    onSearch(){
      console.log('点击搜索按钮',this.ruleForm);
    },
    exportFun(){
      console.log('导出');
    },
    emptyFun(){
      console.log('清空搜索条件');
    },
  }

子组件源码:在components文件夹下创建一个search.vue

<template>
  <div>
    <!-- inline="true" 行内表单模式-->

    <el-form
      :model="ruleForm"
      :rules="searchRules"
      :inline="inline ? inline : false"
      ref="ruleForm"
      class="demo-ruleForm"
      size="small"
    >
      <!-- label-width="80px" -->

      <el-form-item
        v-for="item in commodityMessage"
        :key="item.prop"
        :label="item.label ? item.label +':' : ''"
        :prop="item.prop"
      >
        <el-input
          v-if="!item.optionSelect && !item.isDate"
          v-model="ruleForm[item.prop]"
          :placeholder="item.label ? '请输入'+ item.label : ''"
          :style="item.widths ? 'width'+ item.widths +'% !important;' : 'width:148px'"
          >{{ item.prop }}</el-input
        >
        <el-select
          v-else-if="item.optionSelect && !item.isDate"
          v-model="ruleForm[item.prop]"
          :placeholder="item.label ? '请输入'+ item.label : ''"
          :style="item.widths ? 'width'+ item.widths +'%' : 'width:148px'"
        >
          <el-option
            v-for="ele in item.optionSelect"
            :key="ele.label"
            :label="ele.label"
            :value="ele.value"
          ></el-option>
        </el-select>
        <div v-else-if="item.isDate && !item.optionSelect ">
          <div  class="block" >
            <!-- <span class="demonstration">{{item.label}}</span> -->
            <el-date-picker
              v-model="ruleForm[item.prop]"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期">
            </el-date-picker>
          </div>
        </div>
      </el-form-item>
      <el-form-item v-if="searchBtns && searchBtns.length > 0 >
       <el-button size="mini" v-for="btn in searchBtns" :key="btn.name"  @click="$emit(btn.fun)" :type="btn.type ? btn.type : 'primary'">{{btn.name}}</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  props:{
    inline: {
      type: Boolean,
      default: false
    },
    ruleForm: {
      type: Object,
    },
    commodityMessage: {
      type: Array,
    },
    searchRules: {
      type: Object,
      default() {
        return {}
      }
    },
    searchBtns: {
      type: Array,
      default() {
        return []
      }
    },
    operation: {
      type: Object,
      default() {
        return {}
      }
    },

  },
  data() {
    return {
      activeSataus:0,
    };
  },
};
</script>

<style lang="scss" scoped>
.configurationTxt {
  font-size: 14px;
  padding-bottom: 10px;
}
.commodityMessageBox {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  .el-form-item {
    width: 50%;
  }
}
.Divline {
  width: 100%;
  border-bottom: 1px dashed #ddd;
  margin: 20px 0;
}
.commodityEditBtnBox {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
  margin-top: 30px;
  .el-button {
    margin: 0 40px;
  }
}

//
.el-form-item{
  margin-right: 18px ;
}
//
.stateSpan{
  font-weight: 700;
  margin-right: 10px;
}
.stateBtnBox{
  display: inline-block;
  margin-right: 10px;
}
</style>

父组件使用

<template>
  <div class="setBg">
    <ele-search
      :inline="true"
      :ruleForm="ruleForm"
      :commodityMessage="commodityMessage"
      :searchRules="searchRules"
      :searchBtns="searchBtns"
      @onSearch="onSearch"
      @exportFun="exportFun"
      @emptyFun="emptyFun"
    />
  </div>
</template>
<script>
import eleSearch from "../../components/eleSearch";

export default {
  components: { eleSearch },
  data() {
    return {
      ruleForm: { // v-model绑定
        site:"", //场地
        number: "", //编号
        orderNumber:"",//单号
        orderType: "", //订单状态
        startDate:'',
      },
      commodityMessage: [ //
        {
          label: "下单时间",
          prop: "startDate",
          isDate:true
        },
        {
          label: "场地",
          prop: "site",
          optionSelect: [
            {
              label: "全部",
              value: "shanghai"
            },
            {
              label: "零食区",
              value: "beijing"
            }
          ]
        },
        {
          label: "编号",
          prop: "number",
        },
        {
          label: "单号",
          prop: "orderNumber",
          widths:'500'
        },
        {
          label: "订单状态",
          prop: "orderType",
          optionSelect: [
            {
              label: "全部",
              value: "shanghai"
            },
            {
              label: "待支付",
              value: "zhifu"
            },
            {
              label: "已支付",
              value: "yizhifu"
            },
            {
              label: "已退款",
              value: "yituikuan"
            }
          ]
        },
      ],
      searchRules: { // 校验
        orderNumber: [
          { required: true, message: "请输入单号", trigger: "blur" },
          { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
        ],
        number: [
          { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
        ],
      },
      searchBtns: [ // 按钮们
        {
          name: "搜索",
          fun:'onSearch'
        },
        {
          name: "导出",
          fun:'exportFun'
        },
        {
          name: "清空搜索条件",
          fun:'emptyFun',
          type:'warning'
        },
      ],

    };
  },
  methods: {
    onSearch(){
      console.log('点击搜索按钮',this.ruleForm);
    },
    exportFun(){
      console.log('导出');
    },
    emptyFun(){
      console.log('清空搜索条件');
    },
  }
};
</script>

<style lang="scss" scoped>
</style>