Skip to content

Instantly share code, notes, and snippets.

@wisetc
Created December 6, 2019 07:00
Show Gist options
  • Select an option

  • Save wisetc/34e49349a8b401ea41aa96e0328a3a2d to your computer and use it in GitHub Desktop.

Select an option

Save wisetc/34e49349a8b401ea41aa96e0328a3a2d to your computer and use it in GitHub Desktop.

Revisions

  1. wisetc created this gist Dec 6, 2019.
    165 changes: 165 additions & 0 deletions field-collection.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,165 @@
    <template>
    <div class="field-collection">
    <el-form class="_item" v-for="(form, i) in C" :key="i" inline label-width="120px">
    <el-form-item class="_item__col" :label="type + '编号'">
    <el-input type="text" class="_input-el" v-model="form.number" @change="emitForm" />
    </el-form-item>
    <el-form-item class="_item__col" :label="priceLabel">
    <el-input type="number" class="_input-el" v-model.number="form.price" @change="emitForm" />
    <span class="_price-unit">{{priceUnit}}</span>
    </el-form-item>
    </el-form>
    </div>
    </template>

    <script>
    export default {
    props: {
    count: {
    type: Number,
    default: 1,
    },
    type: {
    type: String,
    validator: function(value) {
    return ['车位', '储物柜', '一卡通'].indexOf(value) !== -1
    },
    },
    },
    name: 'FieldCollection',
    computed: {
    priceUnit() {
    return this.type === '车位' || this.type === '橱柜' ? '元/月' : ''
    },
    priceLabel() {
    return this.type === '车位' || this.type === '橱柜' ? '月租金' : '押金'
    },
    },
    data() {
    return {
    // 因为 type 初值为空,所以 C 的初值最好是放在生命周期中
    C: [],
    }
    },
    created() {
    // 列表原始数据
    this.C = this.initC()
    },
    watch: {
    count(val) {
    //
    this.C = this.getC(val)
    },
    // 类型变化,清空数据
    type() {
    //
    this.C = this.initC()
    },
    },
    methods: {
    initC() {
    return new Array(this.count).fill(this.getOriginForm())
    },
    // 得到表单的初始数据
    getOriginForm() {
    return {
    number: '',
    price: 0,
    priceLabel: this.priceLabel,
    priceUnit: this.priceUnit,
    }
    },
    /**
    * 得到表单列表
    * @param {number} count
    * @returns {any[]}
    */
    getC(count) {
    // count FIN equals C.length
    // if count > C.length: concat C and sub empty form list
    // elif count < C.length: splice C from 0 to count
    const form = this.getOriginForm()
    const len = this.C.length
    if (count > len) {
    return this.C.concat(new Array(count - len).fill(form))
    } else if (count < len) {
    return this.C.slice(0, count)
    }
    return []
    },
    /**
    * 表单是否完整
    * @param {{number: string; price: number}} form
    * @returns {boolean}
    */
    isFormValid(form) {
    return Boolean(form.number) && Boolean(form.price)
    },
    /**
    * 是否完整校验
    * @returns {boolean}
    */
    validate() {
    // if one of form in C has empty value: return false
    if (this.C.length === 0) return false
    else if (this.C.find(form => !this.isFormValid(form))) return false
    return true
    },
    // 输出到表单的值
    getForm() {
    return {
    houseInfoList: JSON.stringify(this.C),
    }
    },
    emitForm() {
    this.$emit('input', this.getForm())
    },
    },
    }
    </script>

    <style lang="scss">
    .field-collection {
    padding: 0 24px;
    margin-bottom: 24px;
    ._item {
    border-top: 1px solid #cccccc;
    padding-top: 22px;
    }
    ._item__col {
    position: relative;
    width: 48%;
    }
    ._price-unit {
    position: absolute;
    top: 0;
    right: 1em;
    }
    ._input-el {
    width: 12em;
    }
    .el-form-item__content {
    min-height: auto;
    }
    ._input-el input[type='number']::-webkit-inner-spin-button {
    display: none;
    }
    }
    </style>