Vue弧形轮播菜单导航栏

搞了个弧形轮播导航栏,轮播有动画过渡,可设置自动轮播,以及手动左右切换,只提供我的实现方法,没有集成为组件,大家可做参考根据自己的需求进行修改,优化封装成组件使用。
视频演示,有点模糊,手机拍的。
在这里插入图片描述
在这里插入图片描述
有什么问题评论见

<template>
  <div class="user_callback">
    <div class="user_pic"
         id="user_pic">
      <span class="prev"></span> <span class="next"></span>
      <ul id="user_call">
        <li v-for="v in backimage"
            :key="v.id"
            @click="routerChoose(v.id)"
            :class="'user_pic'+v.id">
          <img :src="v.img"
               alt="1" />
          <div :class="current===v.id?'info_y':'info'">{{v.title}}</div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import $ from 'jquery'
export default {
  data () {
    return {
      current: 1,
      backimage: [
        {
          id: 1,
          title: '首页',
          img: require("../assets/img/items/icon_home_selected.png")
        },
        {
          id: 2,
          title: '科技专题',
          img: require("../assets/img/items/icon_home_normal.png")
        },
        {
          id: 3,
          title: '能耗专题',
          img: require("../assets/img/items/icon_energy_normal.png")
        },
        {
          id: 4,
          title: '企业专题',
          img: require("../assets/img/items/icon_business_normal.png")
        },
        {
          id: 5,
          title: '经济专题',
          img: require("../assets/img/items/icon_economy_normal.png")
        },
        {
          id: 6,
          title: '停车专题',
          img: require("../assets/img/items/icon_home_normal.png")
        },
        {
          id: 7,
          title: '管网专题',
          img: require("../assets/img/items/icon_pipe_normal.png")
        },
        {
          id: 8,
          title: 'OA专题',
          img: require("../assets/img/items/icon_oa_normal.png")
        }
      ],
    }
  },
  mounted () {
    this.arcSlip()
  },
  methods: {
    routerChoose (id) {
      let backimage = [
        {
          id: 1,
          title: '首页',
          img: require("../assets/img/items/icon_home_normal.png")
        },
        {
          id: 2,
          title: '科技专题',
          img: require("../assets/img/items/icon_home_normal.png")
        },
        {
          id: 3,
          title: '能耗专题',
          img: require("../assets/img/items/icon_energy_normal.png")
        },
        {
          id: 4,
          title: '企业专题',
          img: require("../assets/img/items/icon_business_normal.png")
        },
        {
          id: 5,
          title: '经济专题',
          img: require("../assets/img/items/icon_economy_normal.png")
        },
        {
          id: 6,
          title: '停车专题',
          img: require("../assets/img/items/icon_home_normal.png")
        },
        {
          id: 7,
          title: '管网专题',
          img: require("../assets/img/items/icon_pipe_normal.png")
        },
        {
          id: 8,
          title: 'OA专题',
          img: require("../assets/img/items/icon_oa_normal.png")
        }
      ]
      this.current = id
      if (id === 1) {
        backimage[id - 1].img = require("../assets/img/items/icon_home_selected.png");
      } else if (id === 2) {
        backimage[id - 1].img = require("../assets/img/items/icon_home_selected.png");
      } else if (id === 3) {
        backimage[id - 1].img = require("../assets/img/items/icon_energy_selected.png");
      } else if (id === 4) {
        backimage[id - 1].img = require("../assets/img/items/icon_business_selected.png");
      } else if (id === 5) {
        backimage[id - 1].img = require("../assets/img/items/icon_economy_selected.png");
      } else if (id === 6) {
        backimage[id - 1].img = require("../assets/img/items/icon_home_selected.png");
      } else if (id === 7) {
        backimage[id - 1].img = require("../assets/img/items/icon_pipe_selected.png");
      } else if (id === 8) {
        backimage[id - 1].img = require("../assets/img/items/icon_oa_selected.png");
      }

      this.backimage = backimage
    },
    arcSlip () {
      var that = this
      var oPic = document.getElementById('user_pic');
      var oPrev = that.getByClass(oPic, 'prev')[0];
      var oNext = that.getByClass(oPic, 'next')[0];

      var aLi = oPic.getElementsByTagName('li');

      var arr = [];

      for (var i = 0; i < aLi.length; i++) {
        var oImg = aLi[i].getElementsByTagName('img')[0];

        arr.push([parseInt(getStyle(aLi[i], 'left')), parseInt(getStyle(aLi[i], 'top')),
        getStyle(aLi[i], 'zIndex'), oImg.width, parseFloat(getStyle(aLi[i], 'opacity') * 100)
        ]);
      }


      oPrev.onclick = function moveTP () {

        arr.push(arr[0]);
        arr.shift();
        for (var i = 0; i < aLi.length; i++) {
          var oImg = aLi[i].getElementsByTagName('img')[0];

          aLi[i].style.zIndex = arr[i][2];
          that.startMove(aLi[i], {
            left: arr[i][0],
            top: arr[i][1],
            opacity: arr[i][4]
          });
          that.startMove(oImg, {
            width: arr[i][3]
          });
        }

      }

      oNext.onclick = function moveTN () {
        arr.unshift(arr[arr.length - 1]);
        arr.pop();
        for (var i = 0; i < aLi.length; i++) {
          var oImg = aLi[i].getElementsByTagName('img')[0];

          aLi[i].style.zIndex = arr[i][2];
          that.startMove(aLi[i], {
            left: arr[i][0],
            top: arr[i][1],
            opacity: arr[i][4]
          });
          that.startMove(oImg, {
            width: arr[i][3]
          });
        }
      }
      var moveTime = setInterval(function () {

        oNext.click();

      }, 2000);
      $('#user_pic').hover(function () {

        clearInterval(moveTime);
      }, function () {
        moveTime = setInterval(function () {
          oNext.click();
        }, 2000);
      });

      function getStyle (obj, name) {
        if (obj.currentStyle) {
          return obj.currentStyle[name];
        } else {
          return getComputedStyle(obj, false)[name];
        }
      }
    },
    getByClass (oParent, sClass) {
      var aResult = [];
      var aEle = oParent.getElementsByTagName('*');

      for (var i = 0; i < aEle.length; i++) {
        if (aEle[i].className == sClass) {
          aResult.push(aEle[i]);
        }
      }
      return aResult;
    },
    getStyle (obj, name) {
      if (obj.currentStyle) {
        return obj.currentStyle[name];
      } else {
        return getComputedStyle(obj, false)[name];
      }
    },
    startMove (obj, json, fnEnd) {
      let that = this
      clearInterval(obj.timer);
      obj.timer = setInterval(function () {
        var bStop = true;
        for (var attr in json) {
          var cur = 0;

          if (attr == 'opacity') {
            cur = Math.round(parseFloat(that.getStyle(obj, attr)) * 100);
          } else {
            cur = parseInt(that.getStyle(obj, attr));
          }

          var speed = (json[attr] - cur) / 6;
          speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

          if (cur != json[attr]) bStop = false;

          if (attr == 'opacity') {
            obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
            obj.style.opacity = (cur + speed) / 100;
          } else {
            obj.style[attr] = cur + speed + 'px';
          }
        }

        if (bStop) {
          clearInterval(obj.timer);
          if (fnEnd) fnEnd();
        }

      }, 30)


    }
  }
}
</script>

<style lang="less" scoped>
img {
  border: 0;
}

li {
  list-style: none;
}

.user_callback #user_pic {
  position: relative;
  overflow: hidden;
  background-image: url(../assets/img/router.png);
  background-size: 100% 100%;
  background-position: center center;
  height: 2.3rem;
  // height: 5rem;
  width: 9rem;
  z-index: 2;
  // background: pink;
  margin: 0 auto;
  .info {
    color: #ffffff;
    font-size: 0.2rem;
    margin-top: 0.05rem;
    text-align: center;
    white-space: nowrap;
    background: rgba(13, 38, 141, 0.82);
    padding: 0.1rem;
  }
  .info_y {
    color: #ffffff;
    font-size: 0.2rem;
    margin-top: 0.05rem;
    text-align: center;
    white-space: nowrap;
    background: rgba(244, 197, 72, 0.82);
    padding: 0.1rem;
  }
}

.user_callback #user_pic ul {
  width: 990px;
  height: 285px;
  position: relative;
  top: 20px;
  left: 105px;
}

.user_callback #user_pic ul li {
  position: absolute;
}

.user_callback #user_pic ul img {
  position: relative;
  top: 0;
  left: 0;
}

.user_callback #user_pic ul .user_pic1 {
  left: -75px;
  top: -10px;
  z-index: 0;
}

.user_callback #user_pic ul .user_pic2 {
  left: 3px;
  top: 16px;

  z-index: 2;
}

.user_callback #user_pic ul .user_pic3 {
  left: 85px;
  top: 42px;

  z-index: 3;
}

.user_callback #user_pic ul .user_pic4 {
  left: 167px;
  top: 41px;

  z-index: 4;
}

.user_callback #user_pic ul .user_pic5 {
  left: 243px;
  top: 17px;

  z-index: 3;
}

.user_callback #user_pic ul .user_pic6 {
  left: 316px;
  top: -13px;
  // top: -21px;
  // left: 345px;
  z-index: 2;
}

.user_callback #user_pic ul .user_pic7 {
  left: 345px;
  top: -50px;
  z-index: 1;
}

.user_callback #user_pic ul .user_pic8 {
  left: -99px;
  top: -49px;
  z-index: 0;
}
.user_callback #user_pic ul li.user_pic1 {
  opacity: 0.6;
}

.user_callback #user_pic ul li.user_pic2 {
  opacity: 0.8;
}

.user_callback #user_pic ul li.user_pic3 {
  opacity: 1;
}

.user_callback #user_pic ul li.user_pic4 {
  opacity: 1;
}

.user_callback #user_pic ul li.user_pic5 {
  opacity: 0.8;
}

.user_callback #user_pic ul li.user_pic6 {
  opacity: 0.6;
}

.user_callback #user_pic ul li.user_pic7 {
  opacity: 0.2;
}

.user_callback #user_pic ul li.user_pic8 {
  opacity: 0.2;
}

.user_callback #user_pic ul li.user_pic1 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic ul li.user_pic2 img {
  width: 1rem;
  height: 1rem;
}
.user_callback #user_pic ul li.user_pic3 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic ul li.user_pic4 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic ul li.user_pic5 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic ul li.user_pic6 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic ul li.user_pic7 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic ul li.user_pic8 img {
  width: 1rem;
  height: 1rem;
}

.user_callback #user_pic span {
  display: inline-block;
  *display: inline;
  *zoom: 1;
  width: 80px;
  height: 80px;
  position: absolute;
  top: 160px;
  z-index: 30;
  cursor: pointer;
  opacity: 0.7;
  filter: alpha(opacity=70);
}

.user_callback #user_pic:hover span {
  opacity: 1;
  filter: alpha(opacity=100);
}

.user_callback #user_pic span img {
  width: 80px;
  height: 80px;
  display: block;
}

.user_callback #user_pic span.prev {
  background: url(../assets/img/newIndex/left.png) no-repeat;
  position: absolute;
  top: 100px;
  left: 5px;
  display: inline-block;
  width: 60px;
  height: 60px;
}

.user_callback #user_pic span.next {
  background: url(../assets/img/newIndex/right.png) no-repeat;
  position: absolute;
  top: 100px;
  right: 5px;
  display: inline-block;
  width: 60px;
  height: 60px;
}

.user_callback #user_pic span.prev:hover {
  // background: url(../assets/img/items/icon_business_normal.png) no-repeat;
}

.user_callback #user_pic span.next:hover {
  // background: url(../assets/img/items/icon_business_normal.png) no-repeat;
}

.user_callback {
  overflow: hidden;
}
</style>
Vue侧边菜单栏导航是一种常用的网页导航方式。它通常位于页面的侧边栏,用于展示网站或应用的不同功能页面或模块,并提供用户快速切换页面的功能。 Vue框架提供了开发这种导航组件的便利性。我们可以使用Vue的组件化能力,将侧边菜单栏导航拆分成多个组件,使得每个导航项都可以独立管理和维护。这样,当我们需要增加、删除或修改导航项时,只需要修改相应的组件代码,无需影响其他部分。 在实现侧边菜单栏导航时,我们可以使用Vue Router进行页面的切换。通过在导航菜单组件中配置路由链接,当用户点击某个导航项时,Vue Router会根据配置的路由规则,动态加载对应的组件,并渲染到主内容区域。 为了增加用户体验,我们可以使用Vue的动画效果来实现导航菜单的展开和收起。当用户点击导航菜单的折叠按钮时,我们可以通过动画效果平滑地展开或收起导航菜单,使页面的切换过渡更加流畅。 另外,为了提高导航的可用性,我们可以在导航菜单中添加一些交互效果,比如在用户当前所处页面的导航项上添加高亮效果,以提示用户当前所在的位置。我们也可以为导航菜单项添加一些图标或标识,使得用户更容易辨认各个功能页面。 总之,Vue侧边菜单栏导航是一种简洁、灵活、易于维护的网页导航方式。通过合理的组件划分、使用Vue Router实现页面切换、应用动画效果和交互效果,能够为用户提供良好的导航体验,并提高网站或应用的可用性和用户满意度。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带风的少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值