vue2实现自定义表单

176 阅读1分钟

1.创建多个不同类型的组件:包括数值类型,日期类型,选择类型,多选类型等

    //日期类型
    <template>
    <div :class="item.width==50 ? 'col-xs-6':'col-xs-12'">
        <div class="label"><span v-if="item.is_must==1">*</span>
			{{item.field}}
			<i class="icon iconfont careticon" v-if="item.field_description" @mouseover="isShowCaretTips = true" @mouseleave="isShowCaretTips = false">&#xe77b;</i>
            <span class="caret" v-if="isShowCaretTips">
                {{item.field_description}}
            </span>
		</div>
        <div class="container-fluid" v-show="item">
            <!-- 50% 宽度使用 class="col-xs-6"  100%宽度使用 class="col-xs-12" -->
            <div class="cont-wrap block">
                <template v-if="date_type == 'yearrange'">
                    <IntervalYear  ref="IntervalYear" :placeholder="'请选择'" v-model="item.values"  ></IntervalYear>

                </template>
                    <el-date-picker v-else
                        ref="datapick"
                        :type="date_type"
                        :format="date_format"
                        :value-format="value_format"
                        :placeholder="item.guide_text || '请选择' + item.field"
                        v-model="item.values"
                        @blur="changeDate"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        class="owndate"
                    >
                    </el-date-picker>

            </div>
        </div>
    </div>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
import {host, imghost} from '@/config/config.js'
import IntervalYear from '@/components/timeInputMon/IntervalYear.vue'

export default {
    data() {
        return {
            value1:'',
            date_type: '',          //日期类型 1:年;2:年-月;3:年-月-日;4:年-月-日 时:分;5:年-月-日 时:分:秒;
            date_format: '',        //日期格式
            value_format:'',        //值绑定的格式
            isShowCaretTips:false,  // 显示提示信息
        };
    },
    props: ["item","source"],
    computed: {
        ...mapState([
            'newContract'
        ]),
    },
    components:{
        IntervalYear
    },
    created () {
        if(this.item.values=='Invalid Date'){
            this.item.values=''
        }
        switch (this.item.date_type) {
            case "1":
                this.date_type = 'year'
                this.date_format="yyyy"
                this.value_format = "yyyy"
                if(this.item.format==9){ //format:9区间日期 8单选日期
                    this.date_type = 'yearrange' //(月)区间
                }
                break;
            case "2":
                this.date_type = 'month'
                this.date_format="yyyy-MM"
                this.value_format = "yyyy-MM"
                if(this.item.format==9){ //format:9区间日期 8单选日期
                    this.date_type = 'monthrange' //(月)区间
                    if(this.source=='storage' && this.item.values){
                        this.item.values = this.item.values.split('~')
                    }
                }
                break;
            case "3":
                this.date_type = 'date'
                this.date_format="yyyy-MM-dd"
                this.value_format = "yyyy-MM-dd"
                if(this.item.format==9){ //format:9区间日期 8单选日期
                    this.date_type = 'daterange' //(年月日)区间
                    if(this.source=='storage' && this.item.values){
                        this.item.values = this.item.values.split('~')
                    }
                }
                break;
            case "4":
                this.date_type = 'datetime'
                this.date_format="yyyy-MM-dd HH:mm"
                this.value_format = "yyyy-MM-dd HH:mm"
                if(this.item.format==9){ //format:9区间日期 8单选日期
                    this.date_type = 'datetimerange' //(年月日-时间)区间
                }
                break;
            case "5":
                this.date_type = 'datetime'
                this.date_format="yyyy-MM-dd HH:mm:ss"
                this.value_format = "yyyy-MM-dd HH:mm:ss"
                break;
            default:
                this.date_type = 'date'
                // this.date_format="yyyy年MM月dd日 HH时mm分ss秒"
                this.value_format = "yyyy-MM-dd"
                break;
        }
    },
    watch: {
        ['item.values'](){
            this.changeDate()
            this.$emit('changeComponent',{item:this.item})
        }
    },
    methods: {
        blur(e) {
            this.$refs.datapick.focus()
            e.$data.pickerVisible = false
        },
        focus(e){
            e.$data.pickerVisible = true
        },
        changeDate() {
            if(this.item.field == '合同日期') { //合同日期默认当前日期
                this.newContract.contract_date = this.item.values
            }else if(this.item.field == '到期日期'){
                this.newContract.maturity_date = this.item.values
            }else if(this.item.field == '首期回款日期'||this.item.field == '首次回款日期'){
                this.newContract.first_date = this.item.values
            }
        },
        getNowDate(date){
            let newDate = date ? new Date(date) : new Date()
            let year = newDate.getFullYear()
            let month = newDate.getMonth()+1
            let day = newDate.getDate()
            let m = month < 10 ? '0' + month : month
            let d = day < 10 ? '0' + day : day
            return year + '-' + m + '-' + d
        },
    }
};
</script>

<style lang="scss" scoped>
    @import "./formFields.scss";
    .container-fluid{
        height: 34px;
        line-height: 34px;
    }
</style>


2.建一个itemElement.js,将各个组件引入

// 单行文本输入框组件
export { default as singleLine } from './singleLine.vue';

// 多行文本输入框组件
export { default as multipleLine } from './multipleLine.vue';

// 单行数字输入框组件
export { default as integer } from './integer.vue';

// 日期组件
export { default as datePicker } from './datePicker.vue';

// 地图组件
export { default as mapPicker } from './mapPicker.vue';

// 单选
export { default as singleChoice } from './singleChoice.vue';

// 多选
export { default as multipleChoice } from './multipleChoice.vue';

// 附件
export { default as files } from './files.vue';

// 系统选择字段
export { default as systemSelect } from './systemSelect.vue';

// 产品信息
export { default as productInfo } from './productInfo.vue';

// 产品信息
export { default as repaymentPlan } from './repaymentPlan.vue';

// 部门
export { default as depart } from './depart.vue';

// 人员
export { default as person } from './person.vue';

// 分割线
export { default as dividingLine } from './dividingLine.vue';

3.使用vue内置组件component,也叫做动态组件,作为一个占位符使用,主要根据不同条件展示不同的组件

  • 引入全部子组件 import * as itemElements from '@/components/formFields/itemElement';
  • 通过v-bind:is动态绑定组件名称,如上述代码中的item.fielsType要与所渲染的组件的名称相同
  • 通过:freedomConfig="freedomConfig"方式给子组件传值,通过@changeComponent="changeComponentHandle"
   <template>
   <div>
    <component
        :is="item.fielsType"
         v-for="(item, index) in freedomConfig"
         :key="item.id"
         :item="item"
         :source="source"
         :freedomConfig="freedomConfig"
          @changeComponent="changeComponentHandle"
          @changeShenpi="changeShenpi"
    ></component>
    </div>
  </template>
  <script>
  import * as itemElements from '@/components/formFields/itemElement';
  export default {
      components: {
        ...itemElements,
        approvalShenpiNew,
      },
      data() {
        return {
           freedomConfig:{"id":"75415","field":"客户名称","char":"custom_name","is_system":"1","is_enable":"1","is_approval":"0","is_capital":"0","is_allow":"0","is_must":"1","formtype":"0","control_type":"1","format":"0","width":"50","display_form":"1","guide_text":"","field_description":"","generation_mode":"0","cal_formula":"","deal_formula":"","is_null":"0","decimals_number":"0","show_thousand_sign":"0","values":"","sort":"0","parent_id":"0","default_type":"1","date_type":"0","fielsType":"systemSelect","input_type":"text","custom_id":""}]
        }
      }
  }
  
  </script>