refactor range input to composition api

This commit is contained in:
syuilo 2022-06-30 12:48:42 +09:00 committed by Johann150
parent e47af45407
commit f5d87fbc9e
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1

View file

@ -16,105 +16,82 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { computed, defineAsyncComponent, defineComponent, onMounted, onUnmounted, ref, watch } from 'vue'; import { computed, defineAsyncComponent, onMounted, onUnmounted, ref, watch } from 'vue';
import * as os from '@/os'; import * as os from '@/os';
export default defineComponent({ const props = withDefaults(defineProps<{
props: { modelValue: number;
modelValue: { disabled?: boolean;
type: Number, min: number;
required: false, max: number;
default: 0, step?: number;
}, textConverter?: (value: number) => string,
disabled: { }>(), {
type: Boolean, step: 1,
required: false, textConverter: (v) => v.toString(),
default: false, });
},
min: {
type: Number,
required: false,
default: 0,
},
max: {
type: Number,
required: false,
default: 100,
},
step: {
type: Number,
required: false,
default: 1,
},
autofocus: {
type: Boolean,
required: false,
},
textConverter: {
type: Function,
required: false,
default: (v) => v.toString(),
},
},
setup(props, context) { const emit = defineEmits<{
const containerEl = ref<HTMLElement>(); (ev: 'update:modelValue', value: number): void;
const thumbEl = ref<HTMLElement>(); }>();
const rawValue = ref((props.modelValue - props.min) / (props.max - props.min)); const containerEl = ref<HTMLElement>();
const steppedRawValue = computed(() => { const thumbEl = ref<HTMLElement>();
const rawValue = ref((props.modelValue - props.min) / (props.max - props.min));
const steppedRawValue = computed(() => {
if (props.step) { if (props.step) {
const step = props.step / (props.max - props.min); const step = props.step / (props.max - props.min);
return (step * Math.round(rawValue.value / step)); return (step * Math.round(rawValue.value / step));
} else { } else {
return rawValue.value; return rawValue.value;
} }
}); });
const finalValue = computed(() => { const finalValue = computed(() => {
if (Number.isInteger(props.step)) { if (Number.isInteger(props.step)) {
return Math.round((steppedRawValue.value * (props.max - props.min)) + props.min); return Math.round((steppedRawValue.value * (props.max - props.min)) + props.min);
} else { } else {
return (steppedRawValue.value * (props.max - props.min)) + props.min; return (steppedRawValue.value * (props.max - props.min)) + props.min;
} }
}); });
const thumbWidth = computed(() => { const thumbWidth = computed(() => {
if (thumbEl.value == null) return 0; if (thumbEl.value == null) return 0;
return thumbEl.value!.offsetWidth; return thumbEl.value!.offsetWidth;
}); });
const thumbPosition = ref(0); const thumbPosition = ref(0);
const calcThumbPosition = () => { const calcThumbPosition = () => {
if (containerEl.value == null) { if (containerEl.value == null) {
thumbPosition.value = 0; thumbPosition.value = 0;
} else { } else {
thumbPosition.value = (containerEl.value.offsetWidth - thumbWidth.value) * steppedRawValue.value; thumbPosition.value = (containerEl.value.offsetWidth - thumbWidth.value) * steppedRawValue.value;
} }
}; };
watch([steppedRawValue, containerEl], calcThumbPosition); watch([steppedRawValue, containerEl], calcThumbPosition);
let ro: ResizeObserver | undefined; let ro: ResizeObserver | undefined;
onMounted(() => { onMounted(() => {
ro = new ResizeObserver((entries, observer) => { ro = new ResizeObserver((entries, observer) => {
calcThumbPosition(); calcThumbPosition();
}); });
ro.observe(containerEl.value); ro.observe(containerEl.value);
}); });
onUnmounted(() => { onUnmounted(() => {
if (ro) ro.disconnect(); if (ro) ro.disconnect();
}); });
const steps = computed(() => { const steps = computed(() => {
if (props.step) { if (props.step) {
return (props.max - props.min) / props.step; return (props.max - props.min) / props.step;
} else { } else {
return 0; return 0;
} }
}); });
const onMousedown = (ev: MouseEvent | TouchEvent) => { const onMousedown = (ev: MouseEvent | TouchEvent) => {
ev.preventDefault(); ev.preventDefault();
const tooltipShowing = ref(true); const tooltipShowing = ref(true);
@ -150,7 +127,7 @@ export default defineComponent({
// //
if (beforeValue !== finalValue.value) { if (beforeValue !== finalValue.value) {
context.emit('update:modelValue', finalValue.value); emit('update:modelValue', finalValue.value);
} }
}; };
@ -158,20 +135,7 @@ export default defineComponent({
window.addEventListener('touchmove', onDrag); window.addEventListener('touchmove', onDrag);
window.addEventListener('mouseup', onMouseup, { once: true }); window.addEventListener('mouseup', onMouseup, { once: true });
window.addEventListener('touchend', onMouseup, { once: true }); window.addEventListener('touchend', onMouseup, { once: true });
}; };
return {
rawValue,
finalValue,
steppedRawValue,
onMousedown,
containerEl,
thumbEl,
thumbPosition,
steps,
};
},
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>