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