Vue3 自定义悬浮按钮拖拽+底部tabbar自用

<template>
  <div>
<--div这里悬浮-->
    <div class="menu"
         ref="dragDivImg"
         @click.stop="isShow=!isShow"
         @touchstart.stop="dragStart"
         @touchend.stop="dragEnd"
         @touchmove.stop="dragMove"><img src="../assets/home/menu.png"
           alt=""></div>
    <router-view />
    <van-tabbar v-model="activedd"
                route
                v-if="isShow">
      <van-tabbar-item v-for="(item,i) in iconList"
                       :key="i"
                       :replace="item.url!=='/mapPage'"
                       :to="item.url">
        <span>{{item.name}}</span>
        <template #icon="props">
          <img style="height:27px"
               :src="props.activedd? item.active : item.inactive" />
        </template>
      </van-tabbar-item>
    </van-tabbar>
  </div>
</template>
<script>
import { onMounted, ref, nextTick } from "vue";
export default {

  setup(props) {
    let activedd = ref(0)
//用到参数
    const dragDivImg = ref(null)
    let left = ref(0)//悬浮位置
    let top = ref(0)
    let screenW = ref(0)//屏幕尺寸
    let screenH = ref(0)
    let gapWidth = ref(0)
//结束
    let isShow = ref(true)
    let iconList = ref([
      {
        name: '基层服务',
        active: require('@/assets/home/jcfw.png'),
        inactive: require('@/assets/home/jcfw-a.png'),
        url: '/home'
      },
      {
        name: '警务资讯',
        active: require('@/assets/home/jczl.png'),
        inactive: require('@/assets/home/jczl-a.png'),
        url: '/jczl-home'
      },
      {
        name: '网点黄页',
        active: require('@/assets/home/wyhy.png'),
        inactive: require('@/assets/home/whhy-a.png'),
        url: '/mapPage'
      },
      {
        name: '工作台',
        active: require('@/assets/home/work.png'),
        inactive: require('@/assets/home/work-a.png'),
        url: '/work-home'
      },
    ])


    let clientXY = () => {
      if (window.innerHeight !== undefined) {
        return {
          width: window.innerWidth,
          height: window.innerHeight
        }
      } else if (document.compatMode === "CSS1Compat") {
        return {
          width: document.documentElement.clientWidth,
          height: document.documentElement.clientHeight
        }
      } else {
        return {
          width: document.body.clientWidth,
          height: document.body.clientHeight
        }
      }
    }
    //默认位置
    let checkEnv = () => {
      let clientInfo = clientXY();
      console.log(clientInfo, 'iiiii')
      screenW.value = clientInfo.width;
      screenH.value = clientInfo.height;
      top.value = screenH.value - 92 - 40; //默认位置,自行调整
      left.value = screenW.value - 85; //默认位置,自行调整
      //console.log(left.value, screenW.value, screenH.value, top.value, clientInfo, 'iiiii')
      dragDivImg.value.style.left = left.value + "px"//改变位置
      dragDivImg.value.style.top = top.value + "px"//改变位置
      // console.log(dragDivImg.value.style.left, dragDivImg.value.style)
    }
    //拖拽开始
    let dragStart = (e) => {
      console.log('tuodong')

      dragDivImg.value.style.transition = "none"; //不添加任何过度,防止鼠标移动的时候div原地不动
    }
    //拖拽结束
    let dragEnd = (e) => {
      dragDivImg.value.style.transition = "all 0.5s"; //最后div移动到屏幕边缘的过度属性
      if (left.value > screenW.value / 2) { //看div是偏左还是偏右,判断让div自动靠边站
        left.value = screenW.value - 92 - gapWidth.value;
        dragDivImg.value.style.left = left.value + "px"

      } else {
        left.value = gapWidth.value;
        dragDivImg.value.style.left = left.value + "px"

      }
    }
    let dragMove = (e) => {
      if (e.targetTouches.length === 1) {
        // console.log('tuodong', e.targetTouches)
        let touch = e.targetTouches[0];
        left.value = touch.clientX - 92 / 2;
        top.value = touch.clientY - 92 / 2;

        if (top.value <= 0) { //不能拖出去屏幕
          top.value = 0;
        } else if (top.value > screenH.value - 92) { //不能拖出去屏幕
          top.value = screenH.value - 92
        }
        dragDivImg.value.style.left = left.value + "px"
        dragDivImg.value.style.top = top.value + "px"
      }
    }

    onMounted(() => {
      checkEnv()


    })
    return {
      activedd,
      clientXY,
      checkEnv,
      iconList,
      isShow,
      dragDivImg,
      dragStart,
      dragEnd,
      dragMove

    }
  },


}
</script>
<style lang="scss" scoped>
.menu {
  position: fixed;
  left: calc(100% - 80px);
  top: 80%;
  z-index: 999;

  //cursor: move;
}
</style>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用uni-app提供的自定义组件和样式来实现悬浮底部tabbar。以下是一个简单的示例: 1. 创建一个自定义组件,例如命名为`custom-tabbar`。 2. 在`custom-tabbar`组件中,使用`fixed`定位和负的`bottom`值来实现悬浮底部。 3. 在`custom-tabbar`组件中,添加tabbar的选项卡,并处理点击事件。 4. 在页面中引入`custom-tabbar`组件,并将选项卡的数据传递给组件。 下面是示例代码: ```vue <!-- custom-tabbar.vue --> <template> <view class="custom-tabbar"> <view class="tabbar-item" v-for="(item, index) in tabbarList" :key="index" @click="handleClick(index)"> <image :src="item.icon"></image> <text>{{ item.title }}</text> </view> </view> </template> <script> export default { data() { return { tabbarList: [ { title: '首页', icon: 'home' }, { title: '消息', icon: 'message' }, { title: '我的', icon: 'user' } ] }; }, methods: { handleClick(index) { // 处理点击事件 console.log('点击了第', index + 1, '个选项卡'); } } }; </script> <style> .custom-tabbar { position: fixed; bottom: -10px; /* 负的bottom值,使其悬浮底部 */ width: 100%; height: 50px; background-color: #fff; box-shadow: 0px -2px 4px rgba(0, 0, 0, 0.1); display: flex; justify-content: space-around; align-items: center; } .tabbar-item { display: flex; flex-direction: column; align-items: center; } .tabbar-item image { width: 24px; height: 24px; } .tabbar-item text { font-size: 12px; margin-top: 6px; } </style> ``` 在页面中使用`custom-tabbar`组件: ```vue <!-- index.vue --> <template> <view> <!-- 页面内容 --> <view>内容</view> <!-- 引入自定义tabbar组件 --> <custom-tabbar></custom-tabbar> </view> </template> <script> import CustomTabbar from '@/components/custom-tabbar.vue'; export default { components: { CustomTabbar } }; </script> <style> /* 页面样式 */ </style> ``` 这样,你就可以实现一个自定义悬浮底部tabbar了。你可以根据自己的需求来修改`custom-tabbar`组件的样式和功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值