import {Component, Prop, Vue, Emit, Watch, Model} from 'vue-property-decorator'; @Component export default class EflySlider extends Vue { // @Prop({default: () => 0}) private value!: any; @Prop({default: () => '180px'}) private width!: any; @Prop({default: () => 500}) private max!: number; @Prop({default: () => 0}) private min!: number; @Prop({default: () => 1}) private step!: number; @Prop({default: () => false}) private disabled!: boolean; @Model('input') value!: number; @Emit('input') changed($event: any, type: any = "exterior") { return $event } private slider: any = { min: 0, max: 180, step: 1, x: -1, }; private realMax: any = 0; private lastValue: any = 0; private current: any = { left: 0, start: 0, }; @Watch('value', {immediate: true}) private watchvalue(value: any) { this.init(); } @Watch('min', {immediate: true}) private watchMin(value: any) { } @Watch('max', {immediate: true}) private watchMax(value: any) { let difference: any = (this.max - this.min) % this.step if (difference !== 0) { this.realMax = this.max - difference; } else { this.realMax = this.max } this.slider.step = this.slider.max / ((this.realMax - this.min) / this.step); this.lastValue = this.min; if (this.lastValue > this.realMax) { this.lastValue = this.realMax; this.changed(this.lastValue) this.$emit('change', this.lastValue) } this.init(); } private mounted() { let difference: any = (this.max - this.min) % this.step; if (difference !== 0) { this.realMax = this.max - difference; } else { this.realMax = this.max } this.slider.max = this.$el.clientWidth; this.slider.step = this.slider.max / ((this.realMax - this.min) / this.step); this.lastValue = this.min; this.init(); } private init() { let difference: any = this.value % this.step; let value = 0; if (difference !== 0) { value = this.value - difference; } else { value = this.value } this.current.left = (value - this.min) / (this.realMax - this.min) * this.slider.max; } private dragStart($event: any) { if (this.disabled) return if (this.slider.x === -1) { this.slider.x = $event.screenX - $event.offsetX; } let body = document.getElementsByTagName('body')[0]; body.setAttribute("class", "unselect"); let step = Math.round($event.offsetX / this.slider.step); this.current.left = this.slider.step * step; let value = this.min + this.step * Math.floor(this.current.left / this.slider.step); if (this.lastValue !== value) { this.lastValue = value; // this.changed(value, 'interior'); // this.$emit('change') } this.current.start = $event.clientX; document.onmousemove = (e) => { if (e.screenX >= this.slider.x && e.screenX <= this.slider.x + this.slider.max) { if (this.current.left + (e.clientX - this.current.start) >= this.slider.max) { this.current.left = this.slider.max; this.current.start = e.clientX; } else if (this.current.left + (e.clientX - this.current.start) <= this.slider.min) { this.current.left = this.slider.min; this.current.start = e.clientX; } else { if (e.clientX - this.current.start >= this.slider.step) { // 前进 this.current.left = this.current.left + (e.clientX - this.current.start); this.current.start = e.clientX; } else if (e.clientX - this.current.start < 0) { // εŽι€€ this.current.left = this.slider.step * Math.floor((e.clientX - this.slider.x) / this.slider.step); this.current.start = e.clientX; } } } else if (e.screenX < this.slider.x) { this.current.left = this.slider.min; } else if (e.screenX > this.slider.x + this.slider.max) { this.current.left = this.slider.max; } let value = this.min + this.step * Math.floor(this.current.left / this.slider.step); if (this.lastValue !== value) { this.lastValue = value; this.changed(value, 'interior'); } }; document.onmouseup = (e3) => { document.onmousemove = null; document.onmouseup = null; body.setAttribute("class", ""); this.changed(this.lastValue, 'interior'); this.$emit('change', this.lastValue); }; } // private skipStep($event: any) { // if (this.slider.x === -1) { // this.slider.x = $event.screenX - $event.offsetX; // } // let step = Math.round($event.offsetX / this.slider.step); // this.current.left = this.slider.step * step; // let value = this.min + this.step * Math.floor(this.current.left / this.slider.step); // if (this.lastValue !== value) { // this.lastValue = value; // this.changed(value, 'interior'); // } // } }