<script setup>
import { defineExpose, ref, onMounted, onUnmounted } from 'vue';

/**
 * 组件名称:滑动验证组件
 * 组件描述:用于实现滑动验证功能,验证成功后会触发 statusChange 事件
 */
let sliderState = ref(false)
let verifySuccess = ref(false)
let beginClientX = ref(0)
let maxWidth = ref(0)
const slideWidth = ref(0)

const mouseMoveHandler = (e) => {
  if (sliderState.value) {
    let width = (e.clientX - beginClientX.value) / props.multiple;
    if (width > 0 && width <= maxWidth.value) {
      slideWidth.value = width
    } else if (width > maxWidth.value) {
      slideWidth.value = maxWidth.value
      verifySuccessFun();
    }
  }
}
const moseUpHandler = (e) => {
  sliderState.value = false;
  let width = (e.clientX - beginClientX.value) / props.multiple;
  if (width < maxWidth.value) {
    slideWidth.value = 0
  }
}
const verifySuccessFun = () => {
  verifySuccess.value = true
  emit('statusChange', true)
  document.getElementsByTagName('html')[0].removeEventListener('mousemove', mouseMoveHandler);
  document.getElementsByTagName('html')[0].removeEventListener('mouseup', moseUpHandler);
  slideWidth.value = maxWidth.value
}

const addListener = () => {
  document.getElementsByTagName('html')[0].addEventListener('mousemove', mouseMoveHandler);
  document.getElementsByTagName('html')[0].addEventListener('mouseup', moseUpHandler)
}

const reset = () => { // 重置
  addListener()
  emit('statusChange', false)
  beginClientX.value = 0
  sliderState.value = false
  verifySuccess.value = false
  slideWidth.value = 0
}

onMounted(() => {
  maxWidth.value = sliderContainer.value.offsetWidth - slider.value.offsetWidth;
  addListener()
})

onUnmounted(() => {
  document.getElementsByTagName('html')[0].removeEventListener('mousemove', mouseMoveHandler);
  document.getElementsByTagName('html')[0].removeEventListener('mouseup', moseUpHandler);
})

defineExpose({
  reset,
  sliderState,
  verifySuccess,
  slideWidth,
  mouseDownHandler(e) { // 鼠标在滑块上按下事件
    if (!verifySuccess.value) {
      sliderState.value = true;
      beginClientX.value = e.clientX;
    }
  },
})

const slider = ref(null)
const sliderContainer = ref(null)

const sliderToLeftStyle = {
  left: slideWidth.value + 'px'
}

const sliderLeftWidthStyle = {
  width: slideWidth.value + 28 + 'px'
}
</script setup>
Vue3 滑动验证组件 - 代码示例

原文地址: https://www.cveoy.top/t/topic/nmwQ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录