vue实现移动端靠边可拖动悬浮按钮

完整代码

<template>
    <div class="float_button">
        <div
            @click="onBtnClicked"
            ref="floatButton"
            class="float_info"
            :style="{'width': itemWidth + 'px', 'height': itemHeight + 'px', 'left': left + 'px', 'top': top + 'px'}"
        >
            <img src="../../../assets/img/takeout/home.png" alt="" srcset="">
            <span class="text">{{ text }}</span>
        </div>
    </div>
</template>
<script>
export default {
    data() {
        return {
            clientWidth: 0,
            clientHeight: 0,
            timer: null,
            currentTop: 0,
            left: 0,
            top: 0,
        }
    },
    props: {
        text: {                 // 按钮文本内容
            type: String,
            default: "首页"
        },
        itemWidth: {            // 悬浮按钮宽度
            type: Number,
            default: 40
        },
        itemHeight: {           // 悬浮按钮高度
            type: Number,
            default: 50
        },
        gapWidth: {             // 距离左右两边距离     
            type: Number,
            default: 0
        },
        coefficientHeight: {    // 从上到下距离比例
            type: Number,
            default: 0.55
        }
    },
    created() {
        this.clientWidth = document.documentElement.clientWidth
        this.clientHeight = document.documentElement.clientHeight
        this.left = this.clientWidth - this.itemWidth - this.gapWidth
        this.top = this.clientHeight * this.coefficientHeight
    },
    methods: {
        onBtnClicked(){
            this.$emit("onFloatBtnClicked")
        },
        handleScrollStart() {
            this.timer && clearTimeout(this.timer)
            this.timer = setTimeout(() => {
                this.handleScrollEnd()
            }, 300)
            this.currentTop = document.documentElement.scrollTop || document.body.scrollTop
            if(this.left > this.clientWidth / 2) {
                this.left = this.clientWidth - this.itemWidth / 2
            } else {
                this.left = -this.itemWidth / 2
            }
        },
        handleScrollEnd(){
            let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
            if(scrollTop === this.currentTop) {
                if(this.left > this.clientWidth/2) {
                    this.left = this.clientWidth - this.itemWidth - this.gapWidth
                } else {
                    this.left = this.gapWidth
                }
                clearTimeout(this.timer)
            }
        }
    },
    mounted() {
        this.$nextTick(() => {
            const floatButton = this.$refs.floatButton
            floatButton.addEventListener("touchstart", () => {
                floatButton.style.transition = 'none'
            })
            
            // 在拖拽的过程中,组件应该跟随手指的移动而移动。
            floatButton.addEventListener("touchmove", (e) => {
                console.log('移动中', e)
                if (e.targetTouches.length === 1) {         // 一根手指
                    let touch = e.targetTouches[0]
                    this.left = touch.clientX - 20
                    this.top = touch.clientY - 25
                }
            })
            
			// 拖拽结束以后,重新调整组件的位置并重新设置过度动画。
            floatButton.addEventListener("touchend", () => {
                floatButton.style.transition = 'all 0.3s'
                if(this.left > document.documentElement.clientWidth / 2) {
                    this.left = document.documentElement.clientWidth - 40
                }else{
                    this.left = 0
                }
            })
        })
    },
    beforeDestroy(){
        // 添加监听页面滚动
        window.removeEventListener('scroll', this.handleScrollStart)
    },
    destroyed() {}
}
</script>
<style lang="less">
.float_button {
    .float_info{
        box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.1);
        color: #666666;
        transition: all 0.3s;
        position: fixed;
        bottom: 436px;
        right: 0;
        width: 80px;
        height: 100px;
        display: flex;
        flex-flow: column;
        justify-content: center;
        align-items: center;
        z-index: 999;
        background: rgba(0, 0, 0, 0.5);
        border-radius: 14px;
        cursor: pointer;
        .text{
            font-size: 24px;
            color: #fff;
        }
        img{
            width: 44px;
            height: 44px;
        }
    }
}
</style>

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Vue是一种流行的JavaScript架,用于构建用户界面。要实现移动端观看监控,可以利用Vue来开发一个响应式的监控系统。 首先,可以使用Vue来构建移动端的界面。Vue提供了丰富的工具和组件,可以轻松地创建适应移动设备的界面。通过使用Vue的响应式机制,可以方便地处理移动设备的各种屏幕尺寸和方向变化。 其次,可以利用Vue的数据绑定功能,将监控数据和移动端界面进行关联。监控数据可以从服务器获取,可以使用Vue的Ajax或者WebSocket等技术与服务器进行通信。通过将监控数据绑定到移动端界面上,可以实时更新监控数据,并在移动端上展示。 另外,Vue的事件处理机制可以方便地处理移动设备上的交互操作。例如,可以使用Vue的事件绑定功能来响应移动设备上的触摸事件,实现监控画面的缩放、拖动等交互操作。 此外,移动端观看监控需要考虑图像的加载和播放。可以使用Vue的图片懒加载功能来延迟加载监控图像,以提高移动端的加载速度。同时,可以使用Vue的动画效果功能来实现监控图像的平滑切换和过渡效果。 最后,由于移动端监控通常需要保证实时性和流畅性,可以考虑使用Vue的虚拟滚动功能来优化大量监控图像的展示。通过只渲染可视区域的图像,可以减少移动端的内存占用和页面渲染的性能消耗。 综上所述,利用Vue可以方便地构建移动端观看监控系统,并且可以提供良好的用户界面和交互体验。通过合理地利用Vue的各种功能和工具,可以实现移动端对监控数据的实时观看和交互操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值