index.vue 4.39 KB
Newer Older
lanbaoming's avatar
lanbaoming committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
<template>
    <div class="dict-selector">
        <el-select v-if="formType == 'select'" v-model="valueSync" :placeholder="placeholder || $t('请选择')" :clearable="clearable" :multiple="multiple" :disabled="disabled" @change="val => $emit('change', val)">
            <el-option v-for="dict in formattedList"
                        :key="dict.value" :label="$l(dict, 'label')" :value="dict.value"/>
        </el-select>
        <el-radio-group  v-if="formType == 'radio'" v-model="valueSync" :disabled="disabled">
            <el-radio v-for="dict in formattedList" :label="dict.value" :checked="valueSync === dict.value" :key="dict.value">{{$l(dict, 'label')}}</el-radio>
        </el-radio-group>
        <el-checkbox-group  v-if="formType == 'checkbox'" v-model="valueSync" :disabled="disabled">
            <el-checkbox v-for="dict in formattedList" :label="dict.value" :key="dict.value">{{$l(dict, 'label')}}</el-checkbox>
        </el-checkbox-group>
    </div>
</template>
<script>
const FORMATTERS = {
    "string": String,
    "bool": function(val){
        return [false, 'false', 0, "0"].indexOf(val) < 0
    },
    'number': Number,
    'array': function(val){
        return typeof val == 'string' ? val.split(',').filter(item => item && item !== '') : val
    }
}
export default {
    props:{
        placeholder: {
            type: String,
            default: null
        },
        type: String,
        value: [String, Number, Array, Boolean],
        multiple: Boolean,
        formType:{
            type: String,
            default: 'select'
        },
        formatter: {
            type: [Function, String],
            default: String
        },
        defaultable: Boolean, // 是否默认选择第一个
        disabled: Boolean,
        /**
         * 过滤字典项,用于只使用部分字典项的场景
         */
        filter: {
            type: Function,
            default: () => true
        },
        clearable: Boolean
    },
    data(){
        return {
            valueSync: this.multiple ? [] : null
        }
    },
    computed:{
        dicts(){
          return this.getList(this.type)
        },
        dictList(){
            return this.dicts.filter(this.filter)
        },
        formattedList(){
            let arr = []
            this.dictList.forEach(item => {
                arr.push({
                    label: item.label,
                    labelEn: item.labelEn,
                    value: this.format(item.value),
                    cssClass: item.cssClass,
                    colorType: item.colorType
                })
            })
            return arr
        }
    },
    watch:{
        valueSync(val){
            this.$emit('input', val)
        },
        value(val){
            if(val != this.valueSync)this.setValueSync()
        },
        dictList(){
            this.setDefault()
        }
    },
    created(){
        this.setValueSync()
        this.setDefault()
    },
    methods:{
        format(val){
            if(val === null || val == undefined || val == '') return val
            let formatter = typeof this.formatter == 'function' ? this.formatter : FORMATTERS[this.formatter]
            if(!formatter){
                console.warn('格式器无效', this.formatter)
                return val
            }
            return formatter(val)
        },
        changeValue(val){
          this.valueSync = val
        },
        setValueSync(){
            if(this.value === null || this.value === undefined || this.value === ''){
                return this.valueSync = this.multiple ? [] : this.value
            }
            if(this.multiple){
                let value = this.value || []
                if(typeof this.value == 'string'){
                    value = this.value.split(',').filter(item => item && item != '')
                }
                this.valueSync = value.map(item => this.format(item))
            }else{
                this.valueSync = this.format(this.value)
            }
        },
        getList(){
            return this.getDictDatas(this.type)
        },
        setDefault(){
            if(!this.defaultable) return
            if(this.dictList.length && (this.valueSync === null || this.valueSync == undefined || this.valueSync == '')){
                this.valueSync = this.multiple ? [] : this.formattedList[0].value
            }
        }
    }
}
</script>
<style scoped>
.dict-selector{
    display: inline-block;
}
</style>