Commit 899ad697b046e29a00d661c6b81f94c3adf93b77
Committed by
GitHub
Merge pull request #3043 from iview/pr/3027
Pr/3027
Showing
3 changed files
with
179 additions
and
66 deletions
Show diff stats
examples/routers/slider.vue
1 | -<!--<template>--> | |
2 | - <!--<div style="margin: 0 400px;">--> | |
3 | - <!--<Slider v-model="valueSingle" @on-change="updateSingleDisplayValue"></Slider>--> | |
4 | - <!--<Button @click="randomSingle">change</Button> {{singleDisplayValue}}--> | |
1 | +<template> | |
2 | + <Form :model="formItem" :label-width="80"> | |
3 | + <FormItem label="Input"> | |
4 | + <Input v-model="formItem.input" placeholder="Enter something..."></Input> | |
5 | + </FormItem> | |
6 | + <FormItem label="Select"> | |
7 | + <Select v-model="formItem.select"> | |
8 | + <Option value="beijing">New York</Option> | |
9 | + <Option value="shanghai">London</Option> | |
10 | + <Option value="shenzhen">Sydney</Option> | |
11 | + </Select> | |
12 | + </FormItem> | |
13 | + <FormItem label="DatePicker"> | |
14 | + <Row> | |
15 | + <Col span="11"> | |
16 | + <DatePicker type="date" placeholder="Select date" v-model="formItem.date"></DatePicker> | |
17 | + </Col> | |
18 | + <Col span="2" style="text-align: center">-</Col> | |
19 | + <Col span="11"> | |
20 | + <TimePicker type="time" placeholder="Select time" v-model="formItem.time"></TimePicker> | |
21 | + </Col> | |
22 | + </Row> | |
23 | + </FormItem> | |
24 | + <FormItem label="Radio"> | |
25 | + <RadioGroup v-model="formItem.radio"> | |
26 | + <Radio label="male">Male</Radio> | |
27 | + <Radio label="female">Female</Radio> | |
28 | + </RadioGroup> | |
29 | + </FormItem> | |
30 | + <FormItem label="Checkbox"> | |
31 | + <CheckboxGroup v-model="formItem.checkbox"> | |
32 | + <Checkbox label="Eat"></Checkbox> | |
33 | + <Checkbox label="Sleep"></Checkbox> | |
34 | + <Checkbox label="Run"></Checkbox> | |
35 | + <Checkbox label="Movie"></Checkbox> | |
36 | + </CheckboxGroup> | |
37 | + </FormItem> | |
38 | + <FormItem label="Switch"> | |
39 | + <i-switch v-model="formItem.switch" size="large"> | |
40 | + <span slot="open">On</span> | |
41 | + <span slot="close">Off</span> | |
42 | + </i-switch> | |
43 | + </FormItem> | |
44 | + <FormItem label="Slider"> | |
45 | + <Slider v-model="formItem.slider" range></Slider> | |
46 | + </FormItem> | |
47 | + <FormItem label="Text"> | |
48 | + <Input v-model="formItem.textarea" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="Enter something..."></Input> | |
49 | + </FormItem> | |
50 | + <FormItem> | |
51 | + <Button type="primary">Submit</Button> | |
52 | + <Button type="ghost" style="margin-left: 8px">Cancel</Button> | |
53 | + </FormItem> | |
54 | + </Form> | |
55 | +</template> | |
56 | +<script> | |
57 | + export default { | |
58 | + data () { | |
59 | + return { | |
60 | + formItem: { | |
61 | + input: '', | |
62 | + select: '', | |
63 | + radio: 'male', | |
64 | + checkbox: [], | |
65 | + switch: true, | |
66 | + date: '', | |
67 | + time: '', | |
68 | + slider: [20, 50], | |
69 | + textarea: '' | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + } | |
74 | +</script> | |
75 | + | |
5 | 76 | |
6 | - <!--<Slider v-model="valueRange" range @on-change="updateRangeDisplayValue"></Slider>--> | |
7 | - <!--<Button @click="randomRange">change</Button> {{rangeDisplayValue}}--> | |
77 | + | |
78 | +<!--<template>--> | |
79 | + <!--<div>--> | |
80 | + <!--<Button type="primary" @click="modal1 = true">Display dialog box</Button>--> | |
81 | + <!--<Modal v-model="modal1">--> | |
82 | + <!--<Slider v-model="value2" range show-tip="always"></Slider>--> | |
83 | + <!--</Modal>--> | |
8 | 84 | <!--</div>--> |
9 | 85 | <!--</template>--> |
10 | 86 | <!--<script>--> |
11 | 87 | <!--export default {--> |
12 | 88 | <!--data () {--> |
13 | 89 | <!--return {--> |
14 | - <!--valueSingle: 10,--> | |
15 | - <!--valueRange: [20, 50],--> | |
16 | - <!--singleDisplayValue: 10,--> | |
17 | - <!--rangeDisplayValue: [20, 50]--> | |
18 | - <!--};--> | |
90 | + <!--modal1: false,--> | |
91 | + <!--value2: [20, 50],--> | |
92 | + <!--}--> | |
19 | 93 | <!--},--> |
20 | 94 | <!--methods: {--> |
21 | - <!--updateSingleDisplayValue (val){--> | |
22 | - <!--console.log('updateSingleDisplayValue', val);--> | |
23 | - <!--this.singleDisplayValue = val;--> | |
24 | - <!--},--> | |
25 | - <!--updateRangeDisplayValue (val){--> | |
26 | - <!--console.log('updateRangeDisplayValue', val);--> | |
27 | - <!--this.rangeDisplayValue = val.join(' - ');--> | |
95 | + <!--ok () {--> | |
96 | + <!--this.$Message.info('Clicked ok');--> | |
28 | 97 | <!--},--> |
29 | - <!--randomSingle () {--> | |
30 | - <!--this.valueSingle = this.random(0, 100);--> | |
31 | - <!--},--> | |
32 | - <!--randomRange () {--> | |
33 | - <!--this.valueRange = [this.random(0, 50), this.random(50, 100)];--> | |
34 | - <!--},--> | |
35 | - <!--random (min, max){--> | |
36 | - <!--return Math.round(Math.random() * (max - min)) + min;--> | |
98 | + <!--cancel () {--> | |
99 | + <!--this.$Message.info('Clicked cancel');--> | |
37 | 100 | <!--}--> |
38 | 101 | <!--}--> |
39 | - <!--};--> | |
102 | + <!--}--> | |
40 | 103 | <!--</script>--> |
41 | - | |
42 | - | |
43 | -<template> | |
44 | - <div> | |
45 | - <Button type="primary" @click="modal1 = true">Display dialog box</Button> | |
46 | - <Modal v-model="modal1"> | |
47 | - <Slider v-model="value2" range show-tip="always"></Slider> | |
48 | - </Modal> | |
49 | - </div> | |
50 | -</template> | |
51 | -<script> | |
52 | - export default { | |
53 | - data () { | |
54 | - return { | |
55 | - modal1: false, | |
56 | - value2: [20, 50], | |
57 | - } | |
58 | - }, | |
59 | - methods: { | |
60 | - ok () { | |
61 | - this.$Message.info('Clicked ok'); | |
62 | - }, | |
63 | - cancel () { | |
64 | - this.$Message.info('Clicked cancel'); | |
65 | - } | |
66 | - } | |
67 | - } | |
68 | -</script> | ... | ... |
src/components/slider/slider.vue
... | ... | @@ -8,20 +8,46 @@ |
8 | 8 | :value="exportValue[0]" |
9 | 9 | :disabled="disabled" |
10 | 10 | @on-change="handleInputChange"></Input-number> |
11 | - <div :class="[prefixCls + '-wrap']" ref="slider" @click.self="sliderClick"> | |
11 | + <div | |
12 | + :class="[prefixCls + '-wrap']" | |
13 | + ref="slider" @click.self="sliderClick" | |
14 | + > | |
12 | 15 | <input type="hidden" :name="name" :value="exportValue"> |
13 | 16 | <template v-if="showStops"> |
14 | - <div :class="[prefixCls + '-stop']" v-for="item in stops" :style="{ 'left': item + '%' }" @click.self="sliderClick"></div> | |
17 | + <div | |
18 | + :class="[prefixCls + '-stop']" | |
19 | + v-for="item in stops" | |
20 | + :style="{ 'left': item + '%' }" | |
21 | + @click.self="sliderClick" | |
22 | + ></div> | |
15 | 23 | </template> |
16 | - <div :class="[prefixCls + '-bar']" :style="barStyle" @click.self="sliderClick"></div> | |
24 | + <div | |
25 | + :class="[prefixCls + '-bar']" | |
26 | + :style="barStyle" | |
27 | + @click.self="sliderClick"></div> | |
17 | 28 | <div |
18 | 29 | :class="[prefixCls + '-button-wrap']" |
19 | 30 | :style="{left: minPosition + '%'}" |
20 | 31 | @touchstart="onPointerDown($event, 'min')" |
21 | 32 | @mousedown="onPointerDown($event, 'min')"> |
22 | - <Tooltip :controlled="pointerDown === 'min'" placement="top" :content="tipFormat(exportValue[0])" | |
23 | - :disabled="tipDisabled" :always="showTip === 'always'" ref="minTooltip"> | |
24 | - <div :class="minButtonClasses"></div> | |
33 | + <Tooltip | |
34 | + :controlled="pointerDown === 'min'" | |
35 | + placement="top" | |
36 | + :content="tipFormat(exportValue[0])" | |
37 | + :disabled="tipDisabled" | |
38 | + :always="showTip === 'always'" | |
39 | + ref="minTooltip" | |
40 | + > | |
41 | + <div | |
42 | + :class="minButtonClasses" | |
43 | + tabindex="0" | |
44 | + @focus="handleFocus('min')" | |
45 | + @blur="handleBlur('min')" | |
46 | + @keydown.left="onKeyLeft($event, 'min')" | |
47 | + @keydown.down="onKeyLeft($event, 'min')" | |
48 | + @keydown.right="onKeyRight($event, 'min')" | |
49 | + @keydown.up="onKeyRight($event, 'min')" | |
50 | + ></div> | |
25 | 51 | </Tooltip> |
26 | 52 | </div> |
27 | 53 | <div v-if="range" |
... | ... | @@ -29,9 +55,24 @@ |
29 | 55 | :style="{left: maxPosition + '%'}" |
30 | 56 | @touchstart="onPointerDown($event, 'max')" |
31 | 57 | @mousedown="onPointerDown($event, 'max')"> |
32 | - <Tooltip :controlled="pointerDown === 'max'" placement="top" :content="tipFormat(exportValue[1])" | |
33 | - :disabled="tipDisabled" :always="showTip === 'always'" ref="maxTooltip"> | |
34 | - <div :class="maxButtonClasses"></div> | |
58 | + <Tooltip | |
59 | + :controlled="pointerDown === 'max'" | |
60 | + placement="top" | |
61 | + :content="tipFormat(exportValue[1])" | |
62 | + :disabled="tipDisabled" | |
63 | + :always="showTip === 'always'" | |
64 | + ref="maxTooltip" | |
65 | + > | |
66 | + <div | |
67 | + :class="maxButtonClasses" | |
68 | + tabindex="0" | |
69 | + @focus="handleFocus('max')" | |
70 | + @blur="handleBlur('max')" | |
71 | + @keydown.left="onKeyLeft($event, 'max')" | |
72 | + @keydown.down="onKeyLeft($event, 'max')" | |
73 | + @keydown.right="onKeyRight($event, 'max')" | |
74 | + @keydown.up="onKeyRight($event, 'max')" | |
75 | + ></div> | |
35 | 76 | </Tooltip> |
36 | 77 | </div> |
37 | 78 | </div> |
... | ... | @@ -110,7 +151,11 @@ |
110 | 151 | startX: 0, |
111 | 152 | currentX: 0, |
112 | 153 | startPos: 0, |
113 | - oldValue: val | |
154 | + oldValue: val, | |
155 | + valueIndex: { | |
156 | + min: 0, | |
157 | + max: 1, | |
158 | + }, | |
114 | 159 | }; |
115 | 160 | }, |
116 | 161 | watch: { |
... | ... | @@ -173,7 +218,6 @@ |
173 | 218 | return (val[1] - this.min) / this.valueRange * 100; |
174 | 219 | }, |
175 | 220 | barStyle () { |
176 | - | |
177 | 221 | const style = { |
178 | 222 | width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%' |
179 | 223 | }; |
... | ... | @@ -216,6 +260,30 @@ |
216 | 260 | max = Math.min(this.max, max); |
217 | 261 | return [min, max]; |
218 | 262 | }, |
263 | + getCurrentValue (event, type) { | |
264 | + if (this.disabled) { | |
265 | + return; | |
266 | + } | |
267 | + | |
268 | + const index = this.valueIndex[type]; | |
269 | + if (typeof index === 'undefined') { | |
270 | + return; | |
271 | + } | |
272 | + | |
273 | + return this.currentValue[index]; | |
274 | + }, | |
275 | + onKeyLeft (event, type) { | |
276 | + const value = this.getCurrentValue(event, type); | |
277 | + if (Number.isFinite(value)) { | |
278 | + this.changeButtonPosition(value - this.step, type); | |
279 | + } | |
280 | + }, | |
281 | + onKeyRight (event, type) { | |
282 | + const value = this.getCurrentValue(event, type); | |
283 | + if (Number.isFinite(value)) { | |
284 | + this.changeButtonPosition(value + this.step, type); | |
285 | + } | |
286 | + }, | |
219 | 287 | onPointerDown (event, type) { |
220 | 288 | if (this.disabled) return; |
221 | 289 | event.preventDefault(); |
... | ... | @@ -293,6 +361,14 @@ |
293 | 361 | this.currentValue = [val, this.currentValue[1]]; |
294 | 362 | this.emitChange(); |
295 | 363 | }, |
364 | + | |
365 | + handleFocus (type) { | |
366 | + this.$refs[`${type}Tooltip`].handleShowPopper(); | |
367 | + }, | |
368 | + | |
369 | + handleBlur (type) { | |
370 | + this.$refs[`${type}Tooltip`].handleClosePopper(); | |
371 | + } | |
296 | 372 | }, |
297 | 373 | mounted () { |
298 | 374 | // #2852 | ... | ... |