UNPKG

6.17 kBPlain TextView Raw
1<template>
2 <label
3 class="el-checkbox"
4 :class="[
5 border && checkboxSize ? 'el-checkbox--' + checkboxSize : '',
6 { 'is-disabled': isDisabled },
7 { 'is-bordered': border },
8 { 'is-checked': isChecked }
9 ]"
10 :id="id"
11 >
12 <span class="el-checkbox__input"
13 :class="{
14 'is-disabled': isDisabled,
15 'is-checked': isChecked,
16 'is-indeterminate': indeterminate,
17 'is-focus': focus
18 }"
19 :tabindex="indeterminate ? 0 : false"
20 :role="indeterminate ? 'checkbox' : false"
21 :aria-checked="indeterminate ? 'mixed' : false"
22 >
23 <span class="el-checkbox__inner"></span>
24 <input
25 v-if="trueLabel || falseLabel"
26 class="el-checkbox__original"
27 type="checkbox"
28 :aria-hidden="indeterminate ? 'true' : 'false'"
29 :name="name"
30 :disabled="isDisabled"
31 :true-value="trueLabel"
32 :false-value="falseLabel"
33 v-model="model"
34 @change="handleChange"
35 @focus="focus = true"
36 @blur="focus = false">
37 <input
38 v-else
39 class="el-checkbox__original"
40 type="checkbox"
41 :aria-hidden="indeterminate ? 'true' : 'false'"
42 :disabled="isDisabled"
43 :value="label"
44 :name="name"
45 v-model="model"
46 @change="handleChange"
47 @focus="focus = true"
48 @blur="focus = false">
49 </span>
50 <span class="el-checkbox__label" v-if="$slots.default || label">
51 <slot></slot>
52 <template v-if="!$slots.default">{{label}}</template>
53 </span>
54 </label>
55</template>
56<script>
57 import Emitter from 'element-ui/src/mixins/emitter';
58
59 export default {
60 name: 'ElCheckbox',
61
62 mixins: [Emitter],
63
64 inject: {
65 elForm: {
66 default: ''
67 },
68 elFormItem: {
69 default: ''
70 }
71 },
72
73 componentName: 'ElCheckbox',
74
75 data() {
76 return {
77 selfModel: false,
78 focus: false,
79 isLimitExceeded: false
80 };
81 },
82
83 computed: {
84 model: {
85 get() {
86 return this.isGroup
87 ? this.store : this.value !== undefined
88 ? this.value : this.selfModel;
89 },
90
91 set(val) {
92 if (this.isGroup) {
93 this.isLimitExceeded = false;
94 (this._checkboxGroup.min !== undefined &&
95 val.length < this._checkboxGroup.min &&
96 (this.isLimitExceeded = true));
97
98 (this._checkboxGroup.max !== undefined &&
99 val.length > this._checkboxGroup.max &&
100 (this.isLimitExceeded = true));
101
102 this.isLimitExceeded === false &&
103 this.dispatch('ElCheckboxGroup', 'input', [val]);
104 } else {
105 this.$emit('input', val);
106 this.selfModel = val;
107 }
108 }
109 },
110
111 isChecked() {
112 if ({}.toString.call(this.model) === '[object Boolean]') {
113 return this.model;
114 } else if (Array.isArray(this.model)) {
115 return this.model.indexOf(this.label) > -1;
116 } else if (this.model !== null && this.model !== undefined) {
117 return this.model === this.trueLabel;
118 }
119 },
120
121 isGroup() {
122 let parent = this.$parent;
123 while (parent) {
124 if (parent.$options.componentName !== 'ElCheckboxGroup') {
125 parent = parent.$parent;
126 } else {
127 this._checkboxGroup = parent;
128 return true;
129 }
130 }
131 return false;
132 },
133
134 store() {
135 return this._checkboxGroup ? this._checkboxGroup.value : this.value;
136 },
137
138 /* used to make the isDisabled judgment under max/min props */
139 isLimitDisabled() {
140 const { max, min } = this._checkboxGroup;
141 return !!(max || min) &&
142 (this.model.length >= max && !this.isChecked) ||
143 (this.model.length <= min && this.isChecked);
144 },
145
146 isDisabled() {
147 return this.isGroup
148 ? this._checkboxGroup.disabled || this.disabled || (this.elForm || {}).disabled || this.isLimitDisabled
149 : this.disabled || (this.elForm || {}).disabled;
150 },
151
152 _elFormItemSize() {
153 return (this.elFormItem || {}).elFormItemSize;
154 },
155
156 checkboxSize() {
157 const temCheckboxSize = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
158 return this.isGroup
159 ? this._checkboxGroup.checkboxGroupSize || temCheckboxSize
160 : temCheckboxSize;
161 }
162 },
163
164 props: {
165 value: {},
166 label: {},
167 indeterminate: Boolean,
168 disabled: Boolean,
169 checked: Boolean,
170 name: String,
171 trueLabel: [String, Number],
172 falseLabel: [String, Number],
173 id: String, /* 当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系*/
174 controls: String, /* 当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系*/
175 border: Boolean,
176 size: String
177 },
178
179 methods: {
180 addToStore() {
181 if (
182 Array.isArray(this.model) &&
183 this.model.indexOf(this.label) === -1
184 ) {
185 this.model.push(this.label);
186 } else {
187 this.model = this.trueLabel || true;
188 }
189 },
190 handleChange(ev) {
191 if (this.isLimitExceeded) return;
192 let value;
193 if (ev.target.checked) {
194 value = this.trueLabel === undefined ? true : this.trueLabel;
195 } else {
196 value = this.falseLabel === undefined ? false : this.falseLabel;
197 }
198 this.$emit('change', value, ev);
199 this.$nextTick(() => {
200 if (this.isGroup) {
201 this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]);
202 }
203 });
204 }
205 },
206
207 created() {
208 this.checked && this.addToStore();
209 },
210 mounted() { // 为indeterminate元素 添加aria-controls 属性
211 if (this.indeterminate) {
212 this.$el.setAttribute('aria-controls', this.controls);
213 }
214 },
215
216 watch: {
217 value(value) {
218 this.dispatch('ElFormItem', 'el.form.change', value);
219 }
220 }
221 };
222</script>