Vue3.x之b端锁屏小组件

Content2022/09/27前端CSS

公司领导觉得b端项目太单调

除了加了一些交互动效外,最近还做了一个锁屏组件,效果图如下。

动画.gif

蒙版部分主要用到了css中属性backdrop-filteropen in new window

组件代码如下:

<script setup>
import { ArrowRightBold, Unlock } from '@element-plus/icons-vue'

const open = ref(false)
const slider = ref(null)
const sliderButton = ref(null)
let startX = 0
let distance = 0
let maxDistance = 0
let minDistance = 0
const isTrigger = ref(false)

const onMousedown = (e) => {
  distance = 0
  maxDistance = 0
  minDistance = 0
  isTrigger.value = false

  sliderButton.value.style.transition = ''
  startX = e.screenX
  maxDistance = slider.value.clientWidth - sliderButton.value.clientWidth - 10
  document.addEventListener('mousemove', onMousemove)
  document.addEventListener('mouseup', onMouseup)
}

const onMousemove = (e) => {
  distance = e.screenX - startX
  if (isTrigger.value) {
    distance = maxDistance
  }
  if (distance <= minDistance) {
    distance = minDistance
  }
  if (distance >= maxDistance) {
    distance = maxDistance
    if (!isTrigger.value) {
      isTrigger.value = true
      setTimeout(() => {
        open.value = false
      }, 300)
    }
  }
  if (open.value) {
    sliderButton.value.style.transform = `translateX(${distance}px)`
  }
}

const onMouseup = () => {
  document.removeEventListener('mousemove', onMousemove)
  document.removeEventListener('mouseup', onMouseup)

  if (!isTrigger.value) {
    // 恢复原始状态
    distance = 0
    maxDistance = 0
    minDistance = 0
    isTrigger.value = false

    if (open.value) {
      sliderButton.value.style.transition = 'all 0.4s'
      sliderButton.value.style.transform = `translateX(${distance}px)`
    }
  }
}
watch(
  () => open.value,
  () => {
    if (open.value) {
      isTrigger.value = false
    }
  }
)

const icon = computed(() => {
  return isTrigger.value ? Unlock : ArrowRightBold
})
</script>
最后更新时间 6/12/2025, 2:36:50 AM