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; | ... | ... |