mirror of https://github.com/ElemeFE/element
update input-number and slider
parent
4fcfa04a9b
commit
c641355e4f
|
@ -21,45 +21,45 @@
|
|||
<p>当我们需要标准的数字值时可以用到这个组件,它为你提供了数值输入提供了范围控制和递增递减的步数控制。</p>
|
||||
|
||||
<div class="demo-box demo-input-number">
|
||||
<el-input-number :value.sync="num1"></el-input-number>
|
||||
<el-input-number v-model="num1"></el-input-number>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-input-number :value.sync="num1"></el-input-number>
|
||||
<el-input-number v-model="num1"></el-input-number>
|
||||
```
|
||||
|
||||
## 禁用状态
|
||||
|
||||
<div class="demo-box demo-input-number">
|
||||
<el-input-number :value.sync="num1" :disabled="true"></el-input-number>
|
||||
<el-input-number v-model="num1" :disabled="true"></el-input-number>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-input-number :value.sync="num1" :disabled="true"></el-input-number>
|
||||
<el-input-number v-model="num1" :disabled="true"></el-input-number>
|
||||
```
|
||||
|
||||
## 步数
|
||||
|
||||
<div class="demo-box demo-input-number">
|
||||
<el-input-number :value.sync="num2" :step="2"></el-input-number>
|
||||
<el-input-number v-model="num2" :step="2"></el-input-number>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-input-number :value.sync="num2" :step="2"></el-input-number>
|
||||
<el-input-number v-model="num2" :step="2"></el-input-number>
|
||||
```
|
||||
|
||||
## 尺寸
|
||||
|
||||
<div class="demo-box demo-input-number">
|
||||
<el-input-number :value.sync="num1" size="large"></el-input-number>
|
||||
<el-input-number :value.sync="num1"></el-input-number>
|
||||
<el-input-number :value.sync="num1" size="small"></el-input-number>
|
||||
<el-input-number v-model="num1" size="large"></el-input-number>
|
||||
<el-input-number v-model="num1"></el-input-number>
|
||||
<el-input-number v-model="num1" size="small"></el-input-number>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-input-number :value.sync="num1" size="large"></el-input-number>
|
||||
<el-input-number :value.sync="num1"></el-input-number>
|
||||
<el-input-number :value.sync="num1" size="small"></el-input-number>
|
||||
<el-input-number v-model="num1" size="large"></el-input-number>
|
||||
<el-input-number v-model="num1"></el-input-number>
|
||||
<el-input-number v-model="num1" size="small"></el-input-number>
|
||||
```
|
||||
|
||||
## API
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value1: 0,
|
||||
value2: 50,
|
||||
value3: null,
|
||||
value4: null,
|
||||
value5: null,
|
||||
value6: null,
|
||||
value7: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onChange(value) {
|
||||
console.log(value);
|
||||
|
@ -10,55 +21,55 @@
|
|||
|
||||
## 基本用法
|
||||
|
||||
<el-slider></el-slider>
|
||||
<el-slider v-model="value1"></el-slider>
|
||||
|
||||
```html
|
||||
<el-slider></el-slider>
|
||||
<el-slider v-model="value1"></el-slider>
|
||||
```
|
||||
|
||||
## 定义初始值
|
||||
|
||||
<el-slider :value="50"></el-slider>
|
||||
<el-slider v-model="value2"></el-slider>
|
||||
|
||||
```html
|
||||
<el-slider :value="50"></el-slider>
|
||||
<el-slider v-model="value2"></el-slider>
|
||||
```
|
||||
|
||||
## 定义区间
|
||||
|
||||
<el-slider :min="20" :max="80"></el-slider>
|
||||
<el-slider :min="20" :max="80" v-model="value3"></el-slider>
|
||||
|
||||
```html
|
||||
<el-slider :min="20" :max="80"></el-slider>
|
||||
<el-slider :min="20" :max="80" v-model="value3"></el-slider>
|
||||
```
|
||||
|
||||
## 定义步长
|
||||
|
||||
<el-slider :step="10"></el-slider>
|
||||
<el-slider :step="10" v-model="value4"></el-slider>
|
||||
|
||||
```html
|
||||
<el-slider :step="10"></el-slider>
|
||||
<el-slider :step="10" v-model="value4"></el-slider>
|
||||
```
|
||||
|
||||
## 显示间断点
|
||||
|
||||
<el-slider :step="10" show-stops></el-slider>
|
||||
<el-slider :step="10" show-stops v-model="value5"></el-slider>
|
||||
|
||||
```html
|
||||
<el-slider :step="10" show-stops></el-slider>
|
||||
<el-slider :step="10" show-stops v-model="value5"></el-slider>
|
||||
```
|
||||
|
||||
## 带有输入框
|
||||
|
||||
<el-slider show-input></el-slider>
|
||||
<el-slider show-input v-model="value6"></el-slider>
|
||||
|
||||
```html
|
||||
<el-slider show-input></el-slider>
|
||||
<el-slider show-input v-model="value6"></el-slider>
|
||||
```
|
||||
|
||||
## 回调函数
|
||||
|
||||
<el-slider @change="onChange"></el-slider>
|
||||
<el-slider @change="onChange" v-model="value7"></el-slider>
|
||||
|
||||
```html
|
||||
<template>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
]"
|
||||
>
|
||||
<el-input
|
||||
:value="value"
|
||||
@onchange="handleChnage"
|
||||
v-model="currentValue"
|
||||
@onchange="handleChange"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
:number="true"
|
||||
|
@ -18,17 +18,17 @@
|
|||
<span
|
||||
class="el-input-number__decrease el-icon-minus"
|
||||
:class="{'is-disabled': minDisabled}"
|
||||
v-repeat-click="decrease()"
|
||||
v-repeat-click="decrease"
|
||||
@mouseenter="activeInput(minDisabled)"
|
||||
@mouseleave="unactiveInput(minDisabled)"
|
||||
@mouseleave="inactiveInput(minDisabled)"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
class="el-input-number__increase el-icon-plus"
|
||||
:class="{'is-disabled': maxDisabled}"
|
||||
v-repeat-click="increase()"
|
||||
v-repeat-click="increase"
|
||||
@mouseenter="activeInput(maxDisabled)"
|
||||
@mouseleave="unactiveInput(maxDisabled)"
|
||||
@mouseleave="inactiveInput(maxDisabled)"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -41,8 +41,7 @@
|
|||
name: 'ElInputNumber',
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: true
|
||||
type: Number
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
|
@ -61,13 +60,12 @@
|
|||
},
|
||||
directives: {
|
||||
repeatClick: {
|
||||
bind() {
|
||||
const el = this.el;
|
||||
bind(el, binding, vnode) {
|
||||
let interval = null;
|
||||
let startTime;
|
||||
|
||||
const handler = () => {
|
||||
this.vm.$get(this.expression);
|
||||
vnode.context[binding.expression]();
|
||||
};
|
||||
|
||||
const clear = function() {
|
||||
|
@ -93,9 +91,23 @@
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
currentValue: null,
|
||||
inputActive: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.currentValue = val;
|
||||
}
|
||||
},
|
||||
currentValue(val) {
|
||||
if (!isNaN(parseInt(val, 10))) {
|
||||
this.$emit('input', parseInt(val, 10));
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
minDisabled() {
|
||||
return this.value - this.step < this.min;
|
||||
|
@ -107,14 +119,14 @@
|
|||
methods: {
|
||||
increase() {
|
||||
if (this.value + this.step > this.max || this.disabled) return;
|
||||
this.value += this.step;
|
||||
this.currentValue += this.step;
|
||||
if (this.maxDisabled) {
|
||||
this.inputActive = false;
|
||||
}
|
||||
},
|
||||
decrease() {
|
||||
if (this.value - this.step < this.min || this.disabled) return;
|
||||
this.value -= this.step;
|
||||
this.currentValue -= this.step;
|
||||
if (this.minDisabled) {
|
||||
this.inputActive = false;
|
||||
}
|
||||
|
@ -124,12 +136,12 @@
|
|||
this.inputActive = true;
|
||||
}
|
||||
},
|
||||
unactiveInput(disabled) {
|
||||
inactiveInput(disabled) {
|
||||
if (!this.disabled && !disabled) {
|
||||
this.inputActive = false;
|
||||
}
|
||||
},
|
||||
handleChnage(value) {
|
||||
handleChange(value) {
|
||||
this.$emit('onchange', value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,11 @@
|
|||
},
|
||||
|
||||
watch: {
|
||||
'value'(val) {
|
||||
'value': {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.currentValue = val;
|
||||
}
|
||||
},
|
||||
|
||||
'currentValue'(val) {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div class="el-slider">
|
||||
<el-input-number
|
||||
:value.sync="value"
|
||||
v-model="inputValue"
|
||||
v-if="showInput"
|
||||
class="el-slider__input"
|
||||
@keyup="onInputChange()"
|
||||
v-el:input
|
||||
@keyup.native="onInputChange()"
|
||||
ref="input"
|
||||
:step="step"
|
||||
:min="min"
|
||||
:max="max"
|
||||
|
@ -13,12 +13,14 @@
|
|||
</el-input-number>
|
||||
<div class="el-slider__runway"
|
||||
:class="{ 'show-input': showInput }"
|
||||
@click="onSliderClick($event)" v-el:slider>
|
||||
@click="onSliderClick" ref="slider">
|
||||
<div class="el-slider__bar" :style="{ width: currentPosition }"></div>
|
||||
<div class="el-slider__button-wrapper" @mouseenter="hovering = true" @mouseleave="hovering = false" :style="{left: currentPosition}" v-el:button>
|
||||
<div class="el-slider__button-wrapper" @mouseenter="hovering = true" @mouseleave="hovering = false" :style="{left: currentPosition}" ref="button">
|
||||
<div class="el-slider__button" :class="{ 'hover': hovering, 'dragging': dragging }"></div>
|
||||
</div>
|
||||
<div class="el-slider__pop" v-show="showTip" transition="popper-fade" v-el:pop>{{ value }}</div>
|
||||
<transition name="popper-fade">
|
||||
<div class="el-slider__pop" v-show="showTip" transition="popper-fade" ref="pop">{{ value }}</div>
|
||||
</transition>
|
||||
<div class="el-slider__stop" v-for="item in stops" :style="{ 'left': item + '%' }" v-if="showStops"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -69,6 +71,8 @@
|
|||
|
||||
data() {
|
||||
return {
|
||||
inputValue: null,
|
||||
timeout: null,
|
||||
showTip: false,
|
||||
hovering: false,
|
||||
dragging: false,
|
||||
|
@ -80,18 +84,22 @@
|
|||
},
|
||||
|
||||
watch: {
|
||||
inputValue(val) {
|
||||
this.$emit('input', val);
|
||||
},
|
||||
|
||||
showTip(val) {
|
||||
if (val) {
|
||||
this.$nextTick(() => {
|
||||
this.updatePopper();
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.timeout = setTimeout(() => {
|
||||
if (this.popper) {
|
||||
this.popper.destroy();
|
||||
this.popper = null;
|
||||
}
|
||||
}, 150);
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -100,30 +108,37 @@
|
|||
this.updatePopper();
|
||||
});
|
||||
if (val < this.min) {
|
||||
this.value = this.min;
|
||||
this.$emit('input', this.min);
|
||||
return;
|
||||
}
|
||||
if (val > this.max) {
|
||||
this.value = this.max;
|
||||
this.$emit('input', this.max);
|
||||
return;
|
||||
}
|
||||
this.inputValue = val;
|
||||
this.setPosition((val - this.min) * 100 / (this.max - this.min));
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updatePopper() {
|
||||
if (this.popper) {
|
||||
this.popper.update();
|
||||
} else {
|
||||
this.popper = new Popper(this.$els.button, this.$els.pop, { gpuAcceleration: false, placement: 'top' });
|
||||
this.popper.onCreate(() => {
|
||||
handlePopperStyle() {
|
||||
let placementMap = { top: 'bottom', bottom: 'top' };
|
||||
let placement = this.popper._popper.getAttribute('x-placement').split('-')[0];
|
||||
let origin = placementMap[placement];
|
||||
this.popper._popper.classList.add(placement);
|
||||
this.popper._popper.classList.remove(placementMap[placement]);
|
||||
this.popper._popper.style.transformOrigin = `center ${ origin }`;
|
||||
},
|
||||
|
||||
updatePopper() {
|
||||
if (this.popper) {
|
||||
clearTimeout(this.timeout);
|
||||
this.popper.update();
|
||||
this.handlePopperStyle();
|
||||
} else {
|
||||
this.popper = new Popper(this.$refs.button, this.$refs.pop, { gpuAcceleration: false, placement: 'top' });
|
||||
this.popper.onCreate(() => {
|
||||
this.handlePopperStyle();
|
||||
});
|
||||
this.updatePopper();
|
||||
}
|
||||
|
@ -133,7 +148,7 @@
|
|||
if (newPos >= 0 && (newPos <= 100)) {
|
||||
var lengthPerStep = 100 / ((this.max - this.min) / this.step);
|
||||
var steps = Math.round(newPos / lengthPerStep);
|
||||
this.value = Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min);
|
||||
this.$emit('input', Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min));
|
||||
this.currentPosition = (this.value - this.min) / (this.max - this.min) * 100 + '%';
|
||||
if (!this.dragging) {
|
||||
if (this.value !== this.oldValue) {
|
||||
|
@ -146,8 +161,7 @@
|
|||
|
||||
onSliderClick(event) {
|
||||
var currentX = event.clientX;
|
||||
var sliderOffsetLeft;
|
||||
getStyle(this.$el.parentNode, 'position') === 'static' ? sliderOffsetLeft = this.$els.slider.offsetLeft : sliderOffsetLeft = this.$el.parentNode.offsetLeft + this.$els.slider.offsetLeft;
|
||||
var sliderOffsetLeft = getStyle(this.$el.parentNode, 'position') === 'static' ? this.$refs.slider.offsetLeft : this.$el.parentNode.offsetLeft + this.$refs.slider.offsetLeft;
|
||||
var newPos = (currentX - sliderOffsetLeft) / this.$sliderWidth * 100;
|
||||
this.setPosition(newPos);
|
||||
},
|
||||
|
@ -164,7 +178,7 @@
|
|||
|
||||
computed: {
|
||||
$sliderWidth() {
|
||||
return parseInt(getStyle(this.$els.slider, 'width'), 10);
|
||||
return parseInt(getStyle(this.$refs.slider, 'width'), 10);
|
||||
},
|
||||
|
||||
showTip() {
|
||||
|
@ -183,7 +197,7 @@
|
|||
}
|
||||
},
|
||||
|
||||
compiled() {
|
||||
mounted() {
|
||||
var startX = 0;
|
||||
var currentX = 0;
|
||||
var startPos = 0;
|
||||
|
@ -212,7 +226,7 @@
|
|||
}
|
||||
};
|
||||
|
||||
this.$els.button.addEventListener('mousedown', function(event) {
|
||||
this.$refs.button.addEventListener('mousedown', function(event) {
|
||||
onDragStart(event);
|
||||
window.addEventListener('mousemove', onDragging);
|
||||
window.addEventListener('mouseup', onDragEnd);
|
||||
|
@ -220,9 +234,10 @@
|
|||
},
|
||||
|
||||
created() {
|
||||
if (this.value < this.min || this.value > this.max) {
|
||||
this.value = this.min;
|
||||
if (typeof this.value !== 'number' || this.value < this.min || this.value > this.max) {
|
||||
this.$emit('input', this.min);
|
||||
}
|
||||
this.inputValue = this.inputValue || this.value;
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
color: #fff;
|
||||
cursor: default;
|
||||
z-index: var(--index-top);
|
||||
transition: transform .3s, opacity .3s;
|
||||
transform-origin: center bottom;
|
||||
|
||||
&::before {
|
||||
triangle: 9px top #20A0FF;
|
||||
|
@ -106,13 +108,8 @@
|
|||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.popper-fade-transition {
|
||||
transition: transform .3s, opacity .3s;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
||||
.popper-fade-enter,
|
||||
.popper-fade-leave {
|
||||
.popper-fade-leave-active {
|
||||
transform: scale(0.1);
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue