Vue3 + arco slider 封装的音视频进度条,不受timeupdate更新影响的进度条组件
<template>
<div class="Progress">
<h-slider class="bar" v-model="_modelValue" v-bind="sliderProps" />
</div>
</template>
<script setup>
import { ref, onMounted, watch } from "vue";
const props = defineProps({
modelValue: {
type: Number,
default: 0,
},
sliderProps: {
type: Object,
default: {},
},
});
const emits = defineEmits(["update:modelValue", "changeEnd"]);
const mousedown = ref(false);
const _modelValue = ref(props.modelValue);
watch(
() => props.modelValue,
(val) => {
if (!mousedown.value) {
_modelValue.value = val;
}
}
);
onMounted(() => {
mouseListener();
});
const mouseListener = () => {
document.addEventListener("mousedown", (e) => {
const passClassNameList = ["h-slider-bar", "h-slider-btn", "h-slider-track"];
if (passClassNameList.includes(e.target.className)) {
mousedown.value = true;
}
});
document.addEventListener("mouseup", () => {
if (mousedown.value) {
setTimeout(() => {
emits("changeEnd", _modelValue.value);
emits("update:modelValue", _modelValue.value);
}, 0);
}
mousedown.value = false;
});
};
</script>
<style lang="scss" scoped>
.Progress {
&:deep(.h-slider-track::before) {
height: 4px;
}
&:deep(.h-slider-bar) {
height: 4px;
background: var(--color-theme);
}
&:deep(.h-slider-btn::after) {
border-color: var(--color-theme);
background: var(--color-theme);
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
}
}
</style>