Vue滑块解锁组件使用方法
皮蛋很白 人气:6依据 JS拖动滑块验证 开发的 Vue 滑块解锁组件。
<template> <div ref="wrap" class="slider-unlock"> <div class="before">请按住滑块,拖动到最右边</div> <div ref="after" class="after"> <div class="after-inner">{{ success?'验证成功':'请按住滑块,拖动到最右边' }}</div> </div> <div ref="slider" class="slider" :class="{'is-success': success}" /> </div> </template> <script> export default { name: 'SliderUnlock', data() { return { success: false, clear: null, } }, mounted() { this.init() }, beforeDestroy() { this.clear && this.clear() }, methods: { init() { // 获取 dom const after = this.$refs.after const slider = this.$refs.slider const wrap = this.$refs.wrap // 设置after-inner的固定宽度 after.childNodes[0].style.width = wrap.offsetWidth + 'px' // 滑块移动最大位置 const limit = wrap.offsetWidth - slider.offsetWidth // 实时计算滑块的偏移量 let offsetX // 点击滑块时的鼠标X位置 let initX // 页面鼠标移动事件 const docMousemoveHandler = e => { // 获取移动后鼠标实时位置 const moveX = e.clientX // 计算滑块应该移动的偏移量 offsetX = moveX - initX // 限制上下限 if (offsetX < 0) { offsetX = 0 } else if (offsetX > limit) { offsetX = limit } // 移动滑块 slider.style.left = offsetX + 'px' // 修改高亮背景宽度 after.style.width = offsetX + 'px' if (offsetX >= limit) { this.success = true this.$emit('success') document.removeEventListener('mousemove', docMousemoveHandler) slider.removeEventListener('mousedown', sliderMousedownHandler) } } // 页面鼠标松开事件 const docMouseupHandler = e => { // 解绑事件 document.removeEventListener('mousemove', docMousemoveHandler) // 重置滑块 if (offsetX < limit) { slider.style.left = 0 after.style.width = 0 } } // 滑块点击事件 const sliderMousedownHandler = e => { // 获取鼠标位置 initX = e.clientX // 绑定页面的鼠标移动事件 document.addEventListener('mousemove', docMousemoveHandler) } // 绑定滑块点击事件 slider.addEventListener('mousedown', sliderMousedownHandler) // 页面鼠标松开事件 document.addEventListener('mouseup', docMouseupHandler) // 定义清理方法 this.clear = () => { document.removeEventListener('mousemove', docMousemoveHandler) slider.removeEventListener('mousedown', sliderMousedownHandler) document.removeEventListener('mouseup', docMouseupHandler) } }, }, } </script> <style lang="less" scoped> .slider-unlock{ height: 45px; background: #E1E1E1; border-radius: 4px; position: relative; overflow: hidden; border: 1px solid #CCCCCC; box-sizing: border-box; user-select: none; .before, .after { position: absolute; margin: -1px 0 0 -1px; top: 0; left: 0; z-index: 1; height: 100%; box-sizing: content-box; font-size: 14px; font-weight: bold; line-height: 43px; text-align: center; } .before { width: 100%; color: #333; padding: 0 1px 1px 0; } .after { width: 0; overflow: hidden; padding: 0 0 1px 0; &-inner { position: absolute; width:100%; height: 100%; color: #fff; background-color: #40C057; } } .slider{ position: absolute; margin: -1px 0 0 -1px; top: 0; left: 0; z-index: 3; width: 70px; height: 45px; border: 1px solid #CCC; cursor: pointer; background: no-repeat center center #fff; background-image: url(~@/imgs/icon-allow-right.png); &.is-success { background-image: url(~@/imgs/icon-success.png); } } } </style>
使用:
<SliderUnlock @success="handler" />
效果:
加载全部内容