• Vue + Vant 实现底部导航栏


           我们在做移动端项目的时候,底部导航栏基本可以说是必备的功能,可以方便用户在几大基本页面间切换。一套完整的底部导航栏,不仅需要具有导航菜单的显示,还需要根据实际业务逻辑判断导航栏何时显示、何时隐藏,以及在组件之间进行切换时,添加恰当的页面过渡效果,从而实现整体效果的提升。

           比如从 Home 组件跳转到 Cart 组件时,通过 v-enter、v-leave-to、v-enter-active、v-leave-active 等结合 opacity 属性,设置组件进入、离开时的透明度过渡效果。再进一步,在定义路由时,通过 meta 参数,设置每条路由的 index 参数,通过监听 to、 from 路由对象的 index,并比较t o.meta.index 与 from.meta.index ,前者大页面过渡效果为页面向左滑动,若后者大则过渡效果为页面向右滑动,在 App.vue 中设置好之后,也就为后面的组件提供了非常好的过渡效果。

          这些内容都会在文章中给出代码解决方案。

          效果截图:

        

    主要内容 ( Vant版本:2.9.1 ):

    1、将底部导航栏单独封装,位于:srccomponentsFooterNav.vue :

    2、将 FooterNav 组件引入 App.vue ,以实现全局引用。

    3、设置过渡效果

    1、FooterNav.vue 文件

    1.1 引入 Tabbar:

    import { Tabbar, TabbarItem } from 'vant';

    1.2 组件注册:

    components: {
      [Tabbar.name]: Tabbar,
      [TabbarItem.name]: TabbarItem,
    },

    1.3 设置初始选中标签:

    data() {
      return {
        active: 'home'
      }
    },

    1.4 在 <template></template> 中添加:

    <van-tabbar v-model="active" >
      <van-tabbar-item name="home" icon="home-o">标签</van-tabbar-item>
      <van-tabbar-item name="category" icon="search">标签</van-tabbar-item>
      <van-tabbar-item name="shop-cart" icon="friends-o">标签</van-tabbar-item>
      <van-tabbar-item name="setting" icon="setting-o">标签</van-tabbar-item>
    </van-tabbar>

    2、引入 App.vue

    2.1 引入:

    import FooterNav from './components/FooterNav.vue';

    2.2 组件注册:

    components: {
      "footer-nav": FooterNav,
    }

    注: 组件的名称使用 kebab-case ( 短横线分隔命名 ) 命名,可以很好的避免和当前以及未来的 HTML 元素相冲突。

    2.3 在 <template></template> 中添加:

    <div id="app">
        <!-- main 内容 -->
        <transition :name="mainName">
          <keep-alive v-if="$route.meta.keepAlive">
            <!-- 这里是会被缓存的视图组件 -->
            <router-view id="view" v-if="$route.meta.keepAlive" />
          </keep-alive>
          <!-- 这里是不被缓存的视图组件 -->
          <router-view v-if="!$route.meta.keepAlive && isRouterAlive" id="view" />
        </transition>
    
        <!-- 底部导航 -->
        <transition :name="navName">
          <footer-nav v-if="isShowNav" :activeNavIndex="activeNavIndex"></footer-nav>
        </transition>
    </div>

    2.4 设置 data:

    data() {
      return {
        mainName: '', // 内容区域动画名
        navName: '', // 导航动画名
        isShowNav: false, // 是否显示底部导航 Tab
        activeNavIndex: 0, // 底部导航激活下标
        isRouterAlive: true, // 用于刷新页面用
        navTabs: ['Home', 'Category', 'Cart', 'Me'] // 底部导航
      };
    },

    2.5 设置初始路由

    也就是设置刚进入系统时就进入 home 页面:

    watch: {
      activeNavIndex(newValue) {
        if(newValue === 0) {
          this.$router.push('/home')
        }
      }
    }

     3.设置过滤效果

    3.1 通过 watch 监听路由改变,设置 transition 名称:

    watch: {
      $route (to, from) {
        const {navTabs} = this.$data;
        const toName = to.name;
        const fromName = from.name;
            
        //如果是在 navTab 页面内刷新浏览器或初始进入系统,则显示导航栏
        if(navTabs.includes(toName) && !fromName) this.isShowNav = true;
    switch (toName) {
        case 'home': this.activeNavIndex = 0; break;
          case 'category': this.activeNavIndex = 1; break;
          case 'cart': this.activeNavIndex = 2; break;
          case 'user': this.activeNavIndex = 3; break;
        }
    /* 判断footer-nav是否显示 * 根据meta.index判断页面向左滑动 or 向右滑动 */ // 判断是否是底部导航之间相互切换 if(navTabs.includes(toName) && navTabs.includes(fromName)) { this.mainName = 'fade'; this.isShowNav = true; // 如果 to 索引大于 from 索引, 判断为前进状态, 反之则为后退状态 } else if (to.meta.index > from.meta.index) { this.mainName = 'slide-left'; this.navName = 'nav-slide'; this.isShowNav = false; } else if (to.meta.index < from.meta.index) { this.mainName = 'slide-right'; this.navName = 'nav-slide'; (navTabs.includes(toName))&&(this.isShowNav = true); } } }

    3.2 添加过渡效果:

    //底部导航点进其他页面 导航 tab 动画
    .nav-slide-enter,
    .nav-slide-leave-to {
      transform: translate3d(-100%,0,0)
    }
    .nav-slide-enter-active,
    .nav-slide-leave-active {
      transition: all 5.5s
    }
    // 底部导航之间相互切换 内容区域动画
      .fade-enter { opacity: 0; }
      .fade-leave { opacity: 1; }
      .fade-enter-active { transition: opacity .5s; }
      .fade-leave-active { opacity: 0; transition: opacity 0s; }    //底部导航栏消失时一般为立马消失
    // 前进:右边页面进入的同时,同时左边页面在消失
      .slide-left-enter {   //开始过渡的开始状态为沿X轴向右平移100%,开始过渡结束时向左平移到原位
        transform: translate3d(100%, 0, 0);
      }
      .slide-left-leave-active {
        transform: translate3d(-100%, 0, 0);
      }
      .slide-left-enter-active,
      .slide-left-leave-active {
        will-change: transform;
        transition: all .5s;
        position: absolute; // 解决:页面切换时空白闪屏的问题
      }
    // 后退:左边页面进入的同时,同时右边页面在消失
      .slide-right-enter {
        transform: translate3d(-100%, 0, 0);
      }
      .slide-right-leave-active {
        transform: translate3d(100%, 0, 0);
      }
    
      .slide-left-enter-active,
      .slide-left-leave-active {
        will-change: transform;
        transition: all .5s;
        position: absolute; // 解决:页面切换时空白闪屏的问题
      }

    这样,在 App.vue 全局注册了之后,后面的路由就可以自动应用这些过渡效果了。

    好了,今天的文章就介绍到这里,如果有不正确的地方,欢迎大家留言指正。

  • 相关阅读:
    python使用数据库的一些操作
    正则表达式整理
    tomcat启动成功但是访问不到官网
    控制反转 依赖注入 AOP 和 IOC
    abstract 和 interface区别
    input文本框 鼠标点击默认消失,不输入离开鼠标恢复默认值
    声明式管理事务:基于AspectJ的xml方式
    使用注解配置声明式事务
    spring事物 (mu课)
    oracle表之数据类型
  • 原文地址:https://www.cnblogs.com/Fcode-/p/13255353.html
Copyright © 2020-2023  润新知