<!-- * @Description: * @Autor: renchao * @LastEditTime: 2023-07-25 16:06:03 --> <template> <label class="el-checkbox" :class="[ border && checkboxSize ? 'el-checkbox--' + checkboxSize : '', { 'is-disabled': isDisabled }, { 'is-bordered': border }, { 'is-checked': isChecked } ]" :id="id"> <span class="el-checkbox__input" :class="{ 'is-disabled': isDisabled, 'is-checked': isChecked, 'is-indeterminate': indeterminate, 'is-focus': focus }" :tabindex="indeterminate ? 0 : false" :role="indeterminate ? 'checkbox' : false" :aria-checked="indeterminate ? 'mixed' : false"> <span class="el-checkbox__inner"></span> <input v-if="trueLabel || falseLabel" class="el-checkbox__original" type="checkbox" :aria-hidden="indeterminate ? 'true' : 'false'" :name="name" :disabled="isDisabled" :true-value="trueLabel" :false-value="falseLabel" v-model="model" @change="handleChange" @focus="focus = true" @blur="focus = false"> <input v-else class="el-checkbox__original" type="checkbox" :aria-hidden="indeterminate ? 'true' : 'false'" :disabled="isDisabled" :value="label" :name="name" v-model="model" @change="handleChange" @focus="focus = true" @blur="focus = false"> </span> <span class="el-checkbox__label"> <slot></slot> </span> </label> </template> <script> import Emitter from 'element-ui/src/mixins/emitter'; export default { name: 'ElCheckbox', mixins: [Emitter], inject: { elForm: { default: '' }, elFormItem: { default: '' } }, componentName: 'ElCheckbox', data () { return { selfModel: false, focus: false, isLimitExceeded: false }; }, computed: { model: { /** * @description: get * @author: renchao */ get () { return this.isGroup ? this.store : this.value !== undefined ? this.value : this.selfModel; }, /** * @description: set * @param {*} val * @author: renchao */ set (val) { if (this.isGroup) { this.isLimitExceeded = false; (this._checkboxGroup.min !== undefined && val.length < this._checkboxGroup.min && (this.isLimitExceeded = true)); (this._checkboxGroup.max !== undefined && val.length > this._checkboxGroup.max && (this.isLimitExceeded = true)); this.isLimitExceeded === false && this.dispatch('ElCheckboxGroup', 'input', [val]); } else { this.$emit('input', val); this.selfModel = val; } } }, /** * @description: isChecked * @author: renchao */ isChecked () { if ({}.toString.call(this.model) === '[object Boolean]') { return this.model; } else if (Array.isArray(this.model)) { return this.model.indexOf(this.label) > -1; } else if (this.model !== null && this.model !== undefined) { return this.model === this.trueLabel; } }, /** * @description: isGroup * @author: renchao */ isGroup () { let parent = this.$parent; while (parent) { if (parent.$options.componentName !== 'ElCheckboxGroup') { parent = parent.$parent; } else { this._checkboxGroup = parent; return true; } } return false; }, /** * @description: store * @author: renchao */ store () { return this._checkboxGroup ? this._checkboxGroup.value : this.value; }, /** * @description: isLimitDisabled * @author: renchao */ isLimitDisabled () { const { max, min } = this._checkboxGroup; return !!(max || min) && (this.model.length >= max && !this.isChecked) || (this.model.length <= min && this.isChecked); }, /** * @description: isDisabled * @author: renchao */ isDisabled () { return this.isGroup ? this._checkboxGroup.disabled || this.disabled || (this.elForm || {}).disabled || this.isLimitDisabled : this.disabled || (this.elForm || {}).disabled; }, /** * @description: _elFormItemSize * @author: renchao */ _elFormItemSize () { return (this.elFormItem || {}).elFormItemSize; }, /** * @description: checkboxSize * @author: renchao */ checkboxSize () { const temCheckboxSize = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; return this.isGroup ? this._checkboxGroup.checkboxGroupSize || temCheckboxSize : temCheckboxSize; } }, props: { value: {}, label: {}, indeterminate: Boolean, disabled: Boolean, checked: Boolean, name: String, trueLabel: [String, Number], falseLabel: [String, Number], id: String, /* 当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系*/ controls: String, /* 当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系*/ border: Boolean, size: String }, methods: { /** * @description: addToStore * @author: renchao */ addToStore () { if ( Array.isArray(this.model) && this.model.indexOf(this.label) === -1 ) { this.model.push(this.label); } else { this.model = this.trueLabel || true; } }, /** * @description: handleChange * @author: renchao */ handleChange (ev) { if (this.isLimitExceeded) return; let value; if (ev.target.checked) { value = this.trueLabel === undefined ? true : this.trueLabel; } else { value = this.falseLabel === undefined ? false : this.falseLabel; } this.$emit('change', value, ev); this.$nextTick(() => { if (this.isGroup) { this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]); } }); } }, /** * @description: created * @author: renchao */ created () { this.checked && this.addToStore(); }, /** * @description: mounted * @author: renchao */ mounted () { // 为indeterminate元素 添加aria-controls 属性 if (this.indeterminate) { this.$el.setAttribute('aria-controls', this.controls); } }, /** * @description: watch * @author: renchao */ watch: { value (value) { this.dispatch('ElFormItem', 'el.form.change', value); } } }; </script>