checkbox-button.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <label
  3. class="el-checkbox-button"
  4. :class="[
  5. size ? 'el-checkbox-button--' + size : '',
  6. { 'is-disabled': isDisabled },
  7. { 'is-checked': isChecked },
  8. { 'is-focus': focus },
  9. ]"
  10. role="checkbox"
  11. :aria-checked="isChecked"
  12. :aria-disabled="isDisabled"
  13. >
  14. <input
  15. v-if="trueLabel || falseLabel"
  16. class="el-checkbox-button__original"
  17. type="checkbox"
  18. :name="name"
  19. :disabled="isDisabled"
  20. :true-value="trueLabel"
  21. :false-value="falseLabel"
  22. v-model="model"
  23. @change="handleChange"
  24. @focus="focus = true"
  25. @blur="focus = false">
  26. <input
  27. v-else
  28. class="el-checkbox-button__original"
  29. type="checkbox"
  30. :name="name"
  31. :disabled="isDisabled"
  32. :value="label"
  33. v-model="model"
  34. @change="handleChange"
  35. @focus="focus = true"
  36. @blur="focus = false">
  37. <span class="el-checkbox-button__inner"
  38. v-if="$slots.default || label"
  39. :style="isChecked ? activeStyle : null">
  40. <slot>{{label}}</slot>
  41. </span>
  42. </label>
  43. </template>
  44. <script>
  45. import Emitter from 'element-ui/src/mixins/emitter';
  46. export default {
  47. name: 'ElCheckboxButton',
  48. mixins: [Emitter],
  49. inject: {
  50. elForm: {
  51. default: ''
  52. },
  53. elFormItem: {
  54. default: ''
  55. }
  56. },
  57. data() {
  58. return {
  59. selfModel: false,
  60. focus: false,
  61. isLimitExceeded: false
  62. };
  63. },
  64. props: {
  65. value: {},
  66. label: {},
  67. disabled: Boolean,
  68. checked: Boolean,
  69. name: String,
  70. trueLabel: [String, Number],
  71. falseLabel: [String, Number]
  72. },
  73. computed: {
  74. model: {
  75. get() {
  76. return this._checkboxGroup
  77. ? this.store : this.value !== undefined
  78. ? this.value : this.selfModel;
  79. },
  80. set(val) {
  81. if (this._checkboxGroup) {
  82. this.isLimitExceeded = false;
  83. (this._checkboxGroup.min !== undefined &&
  84. val.length < this._checkboxGroup.min &&
  85. (this.isLimitExceeded = true));
  86. (this._checkboxGroup.max !== undefined &&
  87. val.length > this._checkboxGroup.max &&
  88. (this.isLimitExceeded = true));
  89. this.isLimitExceeded === false &&
  90. this.dispatch('ElCheckboxGroup', 'input', [val]);
  91. } else if (this.value !== undefined) {
  92. this.$emit('input', val);
  93. } else {
  94. this.selfModel = val;
  95. }
  96. }
  97. },
  98. isChecked() {
  99. if ({}.toString.call(this.model) === '[object Boolean]') {
  100. return this.model;
  101. } else if (Array.isArray(this.model)) {
  102. return this.model.indexOf(this.label) > -1;
  103. } else if (this.model !== null && this.model !== undefined) {
  104. return this.model === this.trueLabel;
  105. }
  106. },
  107. _checkboxGroup() {
  108. let parent = this.$parent;
  109. while (parent) {
  110. if (parent.$options.componentName !== 'ElCheckboxGroup') {
  111. parent = parent.$parent;
  112. } else {
  113. return parent;
  114. }
  115. }
  116. return false;
  117. },
  118. store() {
  119. return this._checkboxGroup ? this._checkboxGroup.value : this.value;
  120. },
  121. activeStyle() {
  122. return {
  123. backgroundColor: this._checkboxGroup.fill || '',
  124. borderColor: this._checkboxGroup.fill || '',
  125. color: this._checkboxGroup.textColor || '',
  126. 'box-shadow': '-1px 0 0 0 ' + this._checkboxGroup.fill
  127. };
  128. },
  129. _elFormItemSize() {
  130. return (this.elFormItem || {}).elFormItemSize;
  131. },
  132. size() {
  133. return this._checkboxGroup.checkboxGroupSize || this._elFormItemSize || (this.$ELEMENT || {}).size;
  134. },
  135. /* used to make the isDisabled judgment under max/min props */
  136. isLimitDisabled() {
  137. const { max, min } = this._checkboxGroup;
  138. return !!(max || min) &&
  139. (this.model.length >= max && !this.isChecked) ||
  140. (this.model.length <= min && this.isChecked);
  141. },
  142. isDisabled() {
  143. return this._checkboxGroup
  144. ? this._checkboxGroup.disabled || this.disabled || (this.elForm || {}).disabled || this.isLimitDisabled
  145. : this.disabled || (this.elForm || {}).disabled;
  146. }
  147. },
  148. methods: {
  149. addToStore() {
  150. if (
  151. Array.isArray(this.model) &&
  152. this.model.indexOf(this.label) === -1
  153. ) {
  154. this.model.push(this.label);
  155. } else {
  156. this.model = this.trueLabel || true;
  157. }
  158. },
  159. handleChange(ev) {
  160. if (this.isLimitExceeded) return;
  161. let value;
  162. if (ev.target.checked) {
  163. value = this.trueLabel === undefined ? true : this.trueLabel;
  164. } else {
  165. value = this.falseLabel === undefined ? false : this.falseLabel;
  166. }
  167. this.$emit('change', value, ev);
  168. this.$nextTick(() => {
  169. if (this._checkboxGroup) {
  170. this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]);
  171. }
  172. });
  173. }
  174. },
  175. created() {
  176. this.checked && this.addToStore();
  177. }
  178. };
  179. </script>