vue实现手风琴下拉菜单带动画效果

用vue实现导航菜单的时候,因项目需求要实现下拉菜单带动画效果,而不是简单的显示隐藏,用jquery实现大家应该都会,但是用vue实现怎么办?这就用到了vue的函数式组件

1、
写好导航样式和导航数据列表,渲染出导航列表,引入collapse-transition.js

<style>
    .menu_box{
        width:200px;
        margin:100px auto;
        border:1px solid #f00;
    }
  .mo_menu{
    width:100%;
    line-height:35px;
    font-size:16px;
    border-bottom: 1px solid #F5F5F5;
    transition:.3s;
  }
  .mo_menu .mo_text{
    display: block;
    padding:0px 10px;
    box-sizing: border-box;
    color:#676767;
    transition:.3s;
  }
  .mo_menu .mo_text.no_page{
    color:#003e97;
  }
  .mo_menu.open .mo_text .icon{
    transform: rotate(0deg);
  }
  .mo_menu.open .mo_text{
    color:#003e97;
  }
  .mo_menu .mo_text .icon{
    float:right;
    width:15px;
    height:15px;
    margin:10px 0px;
    transform: rotate(-90deg);
    transition:.3s;
    font-weight: bold;
  }
  .mo_menu .mo_box{
    width:100%;
    overflow: hidden;
  }
  .mo_menu .mo_box .mo_list a{
    line-height:35px;
    padding:0px 10px;
    box-sizing: border-box;
    color:#989898;
    display: block;
    transition:.3s;
  }
  .mo_menu .mo_box .mo_list.active a{
    background:#C9DEFF;
    color:#4D76B2;
  }
</style>
<template>
  <div>
      <ul class="menu_box">
        <li
          v-for="(item,index) in navMenu" 
          :key="index" 
          ref="moMenu"
          :class="[
            {'open': isOpen === index},
            {'has-sub': item.child.length>0},
            'mo_menu',
          ]"
        >
          <router-link 
            class="mo_text" 
            :to="item.path" 
            @click.native="menuOpen($event,index)"
            :class="{
              'no_page': $route.path === `${item.path}`
            }"
          >
            <span>{{item.title}}</span>
            <i class="icon el-icon-arrow-down el-icon--right" v-if="item.child.length>0"></i>
          </router-link>
          <collapse-transition>
            <ul class="mo_box" v-show="item.child.length>0 && isOpen === index">
              <li v-for="items in item.child" 
              :class="[
                'mo_list',
                { 'active': $route.path === `${items.path}` }
              ]">
                <router-link :to="items.path" v-if="items.path">{{items.title}}</router-link>
                <a :href="items.href" :target="items.target" v-if="!items.path">{{items.title}}</a>
              </li>
            </ul>
          </collapse-transition>
        </li>
      </ul>
  </div>
</template>
<script>
import CollapseTransition from './collapse-transition';
export default {
  name: 'NavMenu',
  components:{
    'collapse-transition': CollapseTransition,
  },
  data () {
    return {
      navMenu:[
        {
          id:"0",
          state:0,
          title:"首页",
          path:"/",
          child:[]
        },
        {
          id:"1",
          state:0,
          title:"医疗诊断",
          path:"/medical",
          child:[
            {
              id:"1_1",
              title:"SD1",
              path:"/medical/sd1",
              child:[]
            },
            {
              id:"1_2",
              title:"SMT-120",
              path:"/medical/smt-120",
              child:[]
            },
            {
              id:"1_3",
              title:"医用试剂盘",
              path:"/medical/medical_disc",
              child:[]
            }
          ]
        },
        {
          id:"2",
          state:0,
          title:"动物诊断",
          path:"/animal",
          child:[
            {
              id:"2_1",
              title:"SMT-120V",
              path:"/animal/smt-120v",
              child:[]
            },
            {
              id:"2_2",
              title:"兽用试剂盘",
              path:"/animal/animal_disc",
              child:[]
            },
            {
              id:"2_3",
              title:"病例分享",
              path:"/animal/case_sharing",
              child:[]
            }
          ],
        },
        {
          id:"3",
          state:0,
          title:"新闻中心",
          path:"/news",
          child:[]
        },
        {
          id:"4",
          state:0,
          title:"关于我们",
          path:"/about",
          child:[
            {
              id:"4_1",
              title:"招商中心",
              path:"/about/attrInves",
              child:[]
            },
            {
              id:"4_2",
              title:"资料中心",
              path:"/about/support",
              child:[]
            },
            {
              id:"4_3",
              title:"常见问题",
              path:"/about/problem",
              child:[]
            },
            {
              id:"4_4",
              title:"联系我们",
              path:"/about/contact",
              child:[]
            }
          ]
        }
      ],
      isOpen:-1
    }
  },
  mounted:function(){
    this.$nextTick(()=>{
      this.selectMenu()
    })
  },
  methods:{
    selectMenu(){
      this.navMenu.forEach((item, index) => {
        this.$refs.moMenu[index].firstChild.style = "";
        if (item.child.length > 0) {
          item.child.forEach((child) => {
            if (this.$route.path === `${child.path}`) {
              this.isOpen = index;
            }
          });
        } else {
          if (this.$route.path === `${item.path}`) {
            this.isOpen = -1;
          }
        }
      });
    },
    menuOpen(e,index){
      const target = e.currentTarget;
      if (target.parentNode.className.includes('has-sub')) {
        if (this.isOpen === index) {
          this.isOpen = -1;
        } else {
          this.isOpen = index;
        }
      } else {
        this.isOpen = -1;
      }
      this.navMenu.forEach((item, indexs) => {
        if (index == indexs) {
          this.$refs.moMenu[indexs].firstChild.style.color = "#003e97"
        }else{
          this.$refs.moMenu[indexs].firstChild.style.color = "#676767"
        }
      })
    }
  }
}
</script>

2、
新建collapse-transition.js文件,代码实现如下:

const elTransition = '0.3s height ease-in-out';
const Transition = {
  beforeEnter(el) {
    el.style.transition = elTransition;
    if (!el.dataset) el.dataset = {};
    el.style.height = 0;
  },
  enter(el) {
    if (el.scrollHeight !== 0) {
      el.style.height = `${el.scrollHeight}px`;
    } else {
      el.style.height = '';
    }
    el.style.overflow = 'hidden';
  },
  afterEnter(el) {
    el.style.transition = '';
    el.style.height = '';
  },
  beforeLeave(el) {
    if (!el.dataset) el.dataset = {};
    el.style.display = 'block';
    el.style.height = `${el.scrollHeight}px`;
    el.style.overflow = 'hidden';
  },
  leave(el) {
    if (el.scrollHeight !== 0) {
      el.style.transition = elTransition;
      el.style.height = 0;
    }
  },
  afterLeave(el) {
    el.style.transition = '';
    el.style.height = '';
  },
};
export default {
  name: 'CollapseTransition',
  functional: true,
  render(h, { children }) {
    const data = {
      on: Transition,
    };
    return h('transition', data, children);
  },
};

这样就实现了带动画的下拉菜单,有不懂的朋友欢迎下方留言哦

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值