Commit 98a755be21042406ed404772b0bcf929651c530a
1 parent
4b48b69a
Use native w3c
Showing
4 changed files
with
44 additions
and
34 deletions
Show diff stats
examples/routers/checkbox.vue
src/components/checkbox/checkbox-group.vue
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | <script> |
| 7 | 7 | import { findComponentsDownward, oneOf } from '../../utils/assist'; |
| 8 | 8 | import Emitter from '../../mixins/emitter'; |
| 9 | + | |
| 9 | 10 | const prefixCls = 'ivu-checkbox-group'; |
| 10 | 11 | |
| 11 | 12 | export default { |
| ... | ... | @@ -45,10 +46,9 @@ |
| 45 | 46 | }, |
| 46 | 47 | methods: { |
| 47 | 48 | updateModel (update) { |
| 48 | - const value = this.value; | |
| 49 | 49 | this.childrens = findComponentsDownward(this, 'Checkbox'); |
| 50 | - | |
| 51 | 50 | if (this.childrens) { |
| 51 | + const { value } = this; | |
| 52 | 52 | this.childrens.forEach(child => { |
| 53 | 53 | child.model = value; |
| 54 | 54 | ... | ... |
src/components/checkbox/checkbox.vue
| 1 | 1 | <template> |
| 2 | - <label | |
| 3 | - :class="wrapClasses" | |
| 4 | - @keydown.space.prevent="$el.click()" | |
| 5 | - :tabindex="disabled ? -1 : 0"> | |
| 2 | + <label :class="wrapClasses"> | |
| 6 | 3 | <span :class="checkboxClasses"> |
| 7 | - <span :class="innerClasses"></span> | |
| 4 | + <span :class="innerClasses" ref="inner"></span> | |
| 8 | 5 | <input |
| 9 | 6 | v-if="group" |
| 10 | 7 | type="checkbox" |
| 11 | - tabindex="-1" | |
| 12 | 8 | :class="inputClasses" |
| 13 | 9 | :disabled="disabled" |
| 14 | 10 | :value="label" |
| 15 | 11 | v-model="model" |
| 16 | 12 | :name="name" |
| 17 | 13 | @change="change" |
| 18 | - @focus="$el.focus()" | |
| 19 | - > | |
| 14 | + @focus="onFocus" | |
| 15 | + @blur="onBlur"> | |
| 20 | 16 | <input |
| 21 | - v-if="!group" | |
| 17 | + v-else | |
| 22 | 18 | type="checkbox" |
| 23 | - tabindex="-1" | |
| 24 | 19 | :class="inputClasses" |
| 25 | 20 | :disabled="disabled" |
| 26 | 21 | :checked="currentValue" |
| 27 | 22 | :name="name" |
| 28 | 23 | @change="change" |
| 29 | - @focus="$el.focus()" | |
| 30 | - > | |
| 24 | + @focus="onFocus" | |
| 25 | + @blur="onBlur"> | |
| 31 | 26 | </span> |
| 32 | 27 | <slot><span v-if="showSlot">{{ label }}</span></slot> |
| 33 | 28 | </label> |
| ... | ... | @@ -80,7 +75,8 @@ |
| 80 | 75 | currentValue: this.value, |
| 81 | 76 | group: false, |
| 82 | 77 | showSlot: true, |
| 83 | - parent: findComponentUpward(this, 'CheckboxGroup') | |
| 78 | + parent: findComponentUpward(this, 'CheckboxGroup'), | |
| 79 | + focusInner: false | |
| 84 | 80 | }; |
| 85 | 81 | }, |
| 86 | 82 | computed: { |
| ... | ... | @@ -106,7 +102,12 @@ |
| 106 | 102 | ]; |
| 107 | 103 | }, |
| 108 | 104 | innerClasses () { |
| 109 | - return `${prefixCls}-inner`; | |
| 105 | + return [ | |
| 106 | + `${prefixCls}-inner`, | |
| 107 | + { | |
| 108 | + [`${prefixCls}-focus`]: this.focusInner | |
| 109 | + } | |
| 110 | + ]; | |
| 110 | 111 | }, |
| 111 | 112 | inputClasses () { |
| 112 | 113 | return `${prefixCls}-input`; |
| ... | ... | @@ -114,12 +115,15 @@ |
| 114 | 115 | }, |
| 115 | 116 | mounted () { |
| 116 | 117 | this.parent = findComponentUpward(this, 'CheckboxGroup'); |
| 117 | - if (this.parent) this.group = true; | |
| 118 | - if (!this.group) { | |
| 118 | + if (this.parent) { | |
| 119 | + this.group = true; | |
| 120 | + } | |
| 121 | + | |
| 122 | + if (this.group) { | |
| 123 | + this.parent.updateModel(true); | |
| 124 | + } else { | |
| 119 | 125 | this.updateModel(); |
| 120 | 126 | this.showSlot = this.$slots.default !== undefined; |
| 121 | - } else { | |
| 122 | - this.parent.updateModel(true); | |
| 123 | 127 | } |
| 124 | 128 | }, |
| 125 | 129 | methods: { |
| ... | ... | @@ -131,7 +135,7 @@ |
| 131 | 135 | const checked = event.target.checked; |
| 132 | 136 | this.currentValue = checked; |
| 133 | 137 | |
| 134 | - let value = checked ? this.trueValue : this.falseValue; | |
| 138 | + const value = checked ? this.trueValue : this.falseValue; | |
| 135 | 139 | this.$emit('input', value); |
| 136 | 140 | |
| 137 | 141 | if (this.group) { |
| ... | ... | @@ -143,14 +147,21 @@ |
| 143 | 147 | }, |
| 144 | 148 | updateModel () { |
| 145 | 149 | this.currentValue = this.value === this.trueValue; |
| 150 | + }, | |
| 151 | + onBlur () { | |
| 152 | + this.focusInner = false; | |
| 153 | + }, | |
| 154 | + onFocus () { | |
| 155 | + this.focusInner = true; | |
| 146 | 156 | } |
| 147 | 157 | }, |
| 148 | 158 | watch: { |
| 149 | 159 | value (val) { |
| 150 | - if (val !== this.trueValue && val !== this.falseValue) { | |
| 160 | + if (val === this.trueValue || val === this.falseValue) { | |
| 161 | + this.updateModel(); | |
| 162 | + } else { | |
| 151 | 163 | throw 'Value should be trueValue or falseValue.'; |
| 152 | 164 | } |
| 153 | - this.updateModel(); | |
| 154 | 165 | } |
| 155 | 166 | } |
| 156 | 167 | }; | ... | ... |
src/styles/mixins/checkbox.less
| 1 | 1 | .checkboxFn(@checkbox-prefix-cls: ~"@{css-prefix}checkbox") { |
| 2 | 2 | @checkbox-inner-prefix-cls: ~"@{checkbox-prefix-cls}-inner"; |
| 3 | 3 | |
| 4 | + .@{checkbox-prefix-cls}-focus { | |
| 5 | + box-shadow: 0 0 0 2px fade(@primary-color, 20%); | |
| 6 | + z-index: 1; | |
| 7 | + } | |
| 8 | + | |
| 4 | 9 | // 普通状态 |
| 5 | 10 | .@{checkbox-prefix-cls} { |
| 6 | 11 | display: inline-block; |
| 7 | 12 | vertical-align: middle; |
| 8 | 13 | white-space: nowrap; |
| 9 | 14 | cursor: pointer; |
| 10 | - outline: none; | |
| 15 | + //outline: none; | |
| 11 | 16 | line-height: 1; |
| 12 | 17 | position: relative; |
| 13 | 18 | |
| ... | ... | @@ -236,13 +241,7 @@ |
| 236 | 241 | font-size: @font-size-small; |
| 237 | 242 | display: inline-block; |
| 238 | 243 | margin-right: 8px; |
| 239 | - outline: 0; | |
| 240 | - &:focus, | |
| 241 | - &:active { | |
| 242 | - & .@{checkbox-prefix-cls}-inner { | |
| 243 | - box-shadow: 0 0 0 2px fade(@primary-color, 20%); | |
| 244 | - } | |
| 245 | - } | |
| 244 | + //outline: none; | |
| 246 | 245 | |
| 247 | 246 | &-disabled{ |
| 248 | 247 | cursor: @cursor-disabled; | ... | ... |