个人笔记014--vue实现input和select等的动态布局

今天忙里偷闲整理了一下以前的项目,发现了一个实现动态展示input和select的较好的demo,所以分享一下:

<template>
    <div id="index">
            <div class="Nuser-content">
                <div class="title">用户信息填写</div>
                <div class="input">
                        <div  class="info-unit" v-for="(item,index) in userInfo" :key="index">
                            <div class="grid-content bg-purple">{{item.name}}</div>
                            <div class="discrible must">
                                <template v-if="item.select">
                                    <select class="enter-input"
                                        v-model="item.val">
                                        <option
                                            v-for="val in item.selectObj"
                                            :key="val.value"
                                            :label="val.label"
                                            :value="val.value"
                                        ></option>
                                    </select>
                                </template>
                                <template v-else>
                                        <!-- 如果是密码框则为password,否则为text -->
                                     <input class="enter-input" v-model="item.val" :type=" index == 'password' ? 'password' : 'text' ">
                                </template>
                                <span class="units"></span>
                            </div>
                        </div>
                </div>
            </div>
            <div class="Nuser-xz-content">
                <div class="title">更多信息</div>
                <div class="input">
                       <div v-for="(item,index) in moreInfo"  class="info-unit"  :key="index">
                            <div class="grid-content bg-purple">{{item.name}}</div>
                            <div :class=" item.must ?  'discrible must' : 'discrible'">
                                <template v-if="item.select">
                                    <select class="enter-input"
                                        v-model="item.val">
                                        <option
                                            v-for="val in item.selectObj"
                                            :key="val.value"
                                            :label="val.label"
                                            :value="val.value"
                                        ></option>
                                    </select>
                                </template>
                                <template v-else>
                                     <input class="enter-input" v-model="item.val" >
                                </template>
                                <span class="units"></span>
                            </div>
                      </div>
                  </div>
            </div>
            <div class="Nuser-content-btm">
                <button @click="addUser">保存</button>
            </div>
    </div>
</template>
<script>
export default {
    data(){
        return{
            userInfo:{
                realname:{name:'客户名称',val:'',select:false}, //客户名称(必填)
                mobile:{name:'手机号码',val:'',select:false}, //手机号码(必填)
                password:{name:'密码',val:'',select:false},//密码(必填)
                rlename:{name:'用户角色',val:'',select:true},//用户角色(下拉框)
            },
            moreInfo:{
                sex:{name:'性别',val:'',must:false,select:true}, //性别(下拉框)  //must判断是否为必填选项,select判断是否有下拉框
                lictype:{name:'证件类型',val:'',must:false,select:true}, //证件类型(下拉框)
                liscnum:{name:'证件号码',val:'',must:false,select:false}, //证件号码
                birthday:{name:'生日',val:'',must:false,select:false}, //生日
                linkman:{name:'联系人',val:'',must:false,select:false}, //联系人
                email:{name:'邮箱',val:'',must:false,select:false}, //邮箱
                qq:{name:'QQ',val:'',must:false,select:false}, //QQ
                weixin:{name:'微信',val:'',must:false,select:false}, //微信
                dttid:{name:'所属地区',val:'',must:true,select:false}, //所属地区(必填)
                address:{name:'联系地址',val:'',must:true,select:false}, //联系地址(必填)
                remark:{name:'备注',val:'',must:false,select:false}, //备注
            },
            rlename: [{
                value: 'member',
                label: '平板机用户'
                }, {
                value: 'manager',
                label: '管理员'
            }],
            sex: [{
                value: 'man',
                label: '男'
                }, {
                value: 'woman',
                label: '女'
            }],
            lictype: [{//身份证1、户口本2、驾驶证3、军人证4、学生证5
                value: '1',
                label: '身份证'
                }, {
                value: '2',
                label: '户口本'
                }, {
                value: '3',
                label: '驾驶证'
                }, {
                value: '4',
                label: '军人证'
                }, {
                value: '5',
                label: '学生证'
            }],
        }
    },
    created(){
        this.addSelect(this.userInfo)
        this.addSelect(this.moreInfo)
    },
    methods:{
        // 对象添加下拉框属性
        addSelect(object){
            for (const key in object) {
                if (object[key].select) {
                    object[key].selectObj = this[key]
                }
            }
        },
        // 非空判断
        checkNulll(){
            var str = ''
            for (const key in this.userInfo) {
                // 如果有空值则返回对应的名字
                if(this.userInfo[key].val == '') return str = this.userInfo[key].name;
            }
            // !str表示第一次遍历没空值
            if(!str){
                for (const key in this.moreInfo) {
                    if( this.moreInfo[key].must && this.moreInfo[key].val == '') return str = this.moreInfo[key].name;
                }
            }
            return str
        },
        // 点击按钮
        addUser(){
            var str = this.checkNulll()
            if(str) return alert(str + '不能为空!')
        }
    }
}
</script>

<style scoped>
    #index{
        text-align: left;
        margin: 50px;
        background: #dcc5c5;
        
    }
    .Nuser-content{
        padding: 50px;
        padding-bottom: 0px;
        overflow: hidden;
    }
    .Nuser-xz-content{
        padding: 50px;
        padding-bottom: 0px;
        padding-top: 0px;
    }
    .title{
        font-size:20px;
        font-weight: 600;
    }
    .input{
        line-height: 40px;
        padding: 20px 30px;
        width: 98%;
        overflow: hidden;
    }
    .info-unit{
      float: left;
      width: 25%;
      margin-bottom: 10px;
    }
    .grid-content {
      display: inline-block;
      vertical-align: middle;
      width: 100px;
      height: 40px;
      overflow: hidden;
    }
    .must {
      background: url(./../../static/must.png) no-repeat center left;
      background-size: 8px;
    }
    .enter-input {
        width:100%;
        font-size: inherit;
        vertical-align: middle;
        height: 40px;
        line-height: 40px;
        outline: 0;
        border-radius: 4px;
        border: 1px solid #dcdfe6;
        background-color: rgb(229, 221, 234);
        text-indent: 5px;
        cursor: pointer;
    }
    .discrible {
      display: inline-block;
      width: 55%;
      padding-left: 15px;
      position: relative;
    } 
    .units {
      position: absolute;
      font-size: 14px;
      color: #999;
      right: 10px;
      top: 0px;
    }
    .Nuser-content-btm{
        padding:20px 50px 50px;
    }
    .Nuser-content-btm button{
        padding: 8px 12px;
        margin-right: 20px;
    }
</style>