<template> <div class="dict-selector"> <el-select v-if="formType == 'select'" v-model="valueSync" :placeholder="placeholder" :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: '请选择' }, 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:{ dictList(){ return this.getList(this.type).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>