教你用vue2实现一个tabbar(2024年11月教程)

简介: 欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。自学前端2年半,正向全栈进发。博客分享技术心得,助你成长。关注我,获取更多优质内容,你的支持是我前进的动力!🎉🎉🎉

🎉🎉🎉欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!🙏🙏🙏

@[toc]

1. 实现Tab-Bar思路

  1. 下方单独的Tab-Bar组件如何封装?
    • 自定义Tab-Bar组件,在APP中使用
    • Tab-Bar位置在底部,并设置你需要的样式
  2. Tab-Bar中显示的内容由外部决定
    • 定义插槽
    • flex布局平分Tab-Bar
  3. 自定义Tab-Bar-Item,可以传入图片和文字
    • 定义Tab-Bar-Item,并定义两个插槽:图片和文字
    • 给插槽外层包装div,设置样式
    • 填充插槽,实现底部Tab-Bar的效果
  4. 传入高亮图片
    • 定义另一个插槽,插入active-icon的数据
    • 定义一个变量isActicve,通过v-show来决定是否显示对应的icon
  5. Tab-Bar-Item绑定路由数据
    • 安装路由:npm install vue-router --save
    • router/index.js配置路由信息,并创建对应的组件
    • main.js中注册router
    • App.vue中使用router-linkrouter-view
  6. 点击item跳转到对应的路由,并且动态决定isActive
    • 监听item的点击,通过this.$router.replace()替换路由路径
    • 通过this.$route.path.indexOf(this.link)!==-1来判断是否使active
  7. 动态计算active样式
    • 封装新的计算属性:this.isActive?{'color': 'red'}:{}

2. 代码实现

使用vue init webpack 02-vue-router-tabbar-v1新建一个项目工程(使用vuecli2)。

  1. 在文件夹assest下新建css/base.css,用于初始化css

    base.css

   body {
   
     padding: 0;
     margin: 0;
   }

修改App.vue,添加初步样式

   <template>
     <div id="app">
       <div id="tar-bar">
         <div class="tar-bar-item">首页</div>
         <div class="tar-bar-item">分类</div>
         <div class="tar-bar-item">购物车</div>
         <div class="tar-bar-item">我的</div>
       </div>
     </div>
   </template>

   <script>
   export default {
     name: 'App'
   }
   </script>

   <style>
       /* style中引用使用@import */
     @import url('./assets/css/base.css');

     #tar-bar {
       display: flex;
       background-color: #f6f6f6;

       position: fixed;
       left: 0;
       right: 0;
       bottom: 0;

       box-shadow: 0 -1px  1px rgba(100, 100, 100, .2);
     }

     .tar-bar-item {
       flex: auto;
       text-align: center;
       height: 49px;
       font-size: 20px;
     }
   </style>

使用npm run dev,查看网页效果

                                               ![](https://img-blog.csdnimg.cn/img_convert/d2bcac64e250c41047295ecc0ec2a609.png)

思考:如果每次都要复用tabbar,那每次都需要复制粘贴,应该要把tabbar抽离出来,vue就是组件化思想。

  1. 将tabbar抽离成组件

    在components下新建tabbar文件夹,新建TarBar.vueTabBarItem.vue,TabBarItem组件是在组件TarBar中抽取出来的,可以传入图片和文字(比如首页),所有需要使用插槽<slot>代替。

    TarBar.vue

   <template>
          <div id="tab-bar">
            <!-- 插槽代替tabbaritem -->
            <slot></slot>
          </div>
      </template>
      <script type="text/ecmascript-6">
      export default {
        name: 'TabBar'
      }
      </script>
      <style scoped>
        #tab-bar {
          display: flex;
          background-color: #f6f6f6;
          position: fixed;
          left: 0;
          right: 0;
          bottom: 0;

          box-shadow: 0 -1px  1px rgba(100, 100, 100, .2);
         }
    </style>

TabBar弄一个slot插槽用于插入TabBarItem组件(可能插入多个).

TabBarItem.vue

<template>
    <div class="tab-bar-item">
      <!-- item-icon表示图片插槽 item-text表示文字插槽,例如首页 -->
      <slot name="item-icon"></slot>
      <slot name="item-text"></slot>
    </div>
</template>
<script type="text/ecmascript-6">
  export default {
    name: 'TabBarItem'
  }
</script>
<style scoped>
  .tab-bar-item {
    flex: auto;
    text-align: center;
    height: 49px;
    font-size: 14px;
  }
  .tab-bar-item img {
    height: 24px;
    width: 24px;
    margin-top: 3px;
    vertical-align: middle;
    margin-bottom: 2px;
  }
</style>

TabBarItem组件中插入2个插槽一个用于插入图片一个用于插入文字。

MainTabBar.vue

<template>
  <div class="main-tab-bar">
    <TabBar>
      <TabBarItem path="/home" activeColor="blue">
        <img slot="item-icon" src="~assets/img/tabbar/home.png" alt="" srcset="">
        <template v-slot:item-text>
          <div>首页</div>
        </template>
      </TabBarItem>
      <TabBarItem path="/categories">
        <template #item-icon>
          <img src="~assets/img/tabbar/categories.png" alt="" srcset="">
        </template>
        <template #item-text>
          <div>分类</div>
        </template>
      </TabBarItem>
      <TabBarItem path="/shop">
        <template #item-icon>
          <img src="~assets/img/tabbar/shopcart.png" alt="" srcset="">
        </template>
        <template #item-text>
          <div>购物车</div>
        </template>
      </TabBarItem>
      <TabBarItem path="/me">
        <template #item-icon>
          <img src="~assets/img/tabbar/profile.png" alt="" srcset="">
        </template>
        <template #item-text>
          <div>我的</div>
        </template>
      </TabBarItem>
    </TabBar>
  </div>
</template>
<script type="text/ecmascript-6">
  import TabBar from "@/components/tabbar/TabBar"
  import TabBarItem from "@/components/tabbar/TabBarItem"
  export default {
    name: "MainTabBar",
    components: {
      TabBar,
      TabBarItem
    }
  }
</script>
<style scoped>
</style>

在MainTabBar组件中加入另外2个组件。

注意此处使用~assets@/components是使用了别名配置,详情请看3.别名配置

最后在app.vue中导入MainTabBar组件。

<template>
  <div id="app">
    <MainTabBar></MainTabBar>
  </div>
</template>
<script>
  import MainTabBar from '@/components/MainTabBar'
  export default {
    name: 'App',
    components: {
      MainTabBar
    }
  }
</script>
<style>
    /* style中引用使用@import */
  @import url('./assets/css/base.css');
</style>

效果如图所示,将组件进行了分离重组,只要修改MainTabBar组件就可以修改图片和文字描述,可以复用。

  1. 如何实现点击首页首页字体变红图片变红色

    这里需要用到路由的active-class

    思路:引用2张图片,一张是正常颜色一张是红色,使用v-ifv-else来处理是否变色,在路由处于活跃状态的时候,变红色。

    引入路由使用路由就不细说了,这里仅贴上tabbar的修改代码。

    TabBarItem.vue组件

    <template>
        <div class="tab-bar-item" :style="activeStyle" @click="itemClick">
          <!-- item-icon表示图片插槽 item-text表示文字插槽,例如首页 -->
          <div v-if="!isActive">
            <slot  name="item-icon"></slot>
          </div>
          <div  v-else>
            <slot name="item-icon-active"></slot>
          </div>
          <div :class="{active:isActive}">
            <slot name="item-text"></slot>
          </div>
        </div>
    </template>
    
    <script type="text/ecmascript-6">
      export default {
        name: 'TabBarItem',
        props:{
          path:String,
          activeColor:{
            type:String,
            default:'red'
          }
        },
        computed: {
          isActive(){
            return this.$route.path.indexOf(this.path) !== -1
          },
          activeStyle(){
            return this.isActive ? {color: this.activeColor} : {}
          }
        },
        methods: {
          itemClick(){
            this.$router.push(this.path)
          }
        }
      }
    </script>
    
    <style scoped>
      .tab-bar-item {
        flex: auto;
        text-align: center;
        height: 49px;
        font-size: 14px;
      }
    
      .tab-bar-item img {
        height: 24px;
        width: 24px;
        margin-top: 3px;
        vertical-align: middle;
        margin-bottom: 2px;
      }
    </style>
    
  1. 使用props获取传递的值,这里传递是激活颜色,默认是红色
  2. 设置计算属性isActiveactiveStyle,分别表示激活状态和激活的样式
  3. 定义itemClick()方法用于获取点击事件,点击后使用代码实现路由跳转,这里使用默认的hash模式
  4. 使用v-ifv-else来进行条件判断

    MainTabBar.vue组件

       <TabBarItem path="/home">
         <img slot="item-icon" src="~assets/img/tabbar/home.png" alt="" srcset="">
         <img slot="item-icon-active" src="~assets/img/tabbar/home_active.png" alt="" srcset="">
         <template v-slot:item-text>
           <div>首页</div>
         </template>
       </TabBarItem>
    

    添加激活状态的图片与未激活的图片并列。

  1. 配置路由信息,参考之前的代码

    ```js
    import Vue from 'vue'
    import Router from 'vue-router'

Vue.use(Router)

const routes = [
{
path: '/',
redirect: '/home'//缺省时候重定向到/home
},
{
path: '/home',
component: () => import ('../views/home/Home.vue')
},
{
path: '/categories',
component: () => import ('../views/categories/Categories.vue')
},
{
path: '/shop',
component: () => import ('../views/shop/Shop.vue')
},
{
path: '/profile',
component: () => import ('../views/profile/Profile.vue')
},
]

export default new Router({
routes,
// linkActiveClass:"active"
})


   ![](https://img-blog.csdnimg.cn/img_convert/ae74ed82b3195905237cf13507385c9e.png)

5. 修改main.js和App.vue

   ```js
   import Vue from 'vue'
   import App from './App'
   import router from './router'

   Vue.config.productionTip = false

   /* eslint-disable no-new */
   new Vue({
     el: '#app',
     router,
     render: h => h(App)
   })
   <template>
     <div id="app">
       <router-view></router-view>
       <MainTabBar></MainTabBar>
     </div>
   </template>

   <script>
     import MainTabBar from '@/components/MainTabBar'
     export default {
       name: 'App',
       components: {
         MainTabBar
       }
     }
   </script>

   <style>
       /* style中引用使用@import */
     @import url('./assets/css/base.css');

   </style>

3. 别名配置

经常的我们向引入图片文件等资源的时候使用相对路径,诸如../assets/xxx这样的使用../获取上一层,如果有多个上层就需要../../xxx等等这样不利于维护代码。此时就需要一个能获取到指定目录的资源的就好了。

配置

webpack.base.config中配置使用别名,找到resolve:{}模块,增加配置信息

  resolve: {
   
    extensions: ['.js', '.vue', '.json'],
    alias: {
   
      '@': resolve('src'),
      'assets': resolve('src/assets'),
      'components': resolve('src/components'),
      'views': resolve('scr/views')
    }
  },

这里@指定目录是src,例如@/components表示src/components目录,assets表示src/assets前缀,如果是assets/img就表示src/assets/img目录。

Hi👋,这里是瑞雨溪一个喜欢JavaScript和Vue的大学生,如果我的文章给你带来的帮助,欢迎您关注我,我会持续不断的更新更多优质文章.你的关注就是我的动力!!!🎉🎉🎉

目录
相关文章
|
Java 应用服务中间件 程序员
Maven教程--下(包括手动实现)
Maven教程--下(包括手动实现)
183 0
|
10月前
|
JavaScript 前端开发 C++
关于Vue2里 v-for和v-if一起用的时候会出现的问题
本文介绍了在Vue2中同时使用`v-for`和`v-if`指令时可能出现的问题及解决方案。由于`v-for`的优先级高于`v-if`,导致条件判断在每次循环中执行,可能造成重复渲染。文中通过具体案例展示了问题现象,并提供了两种解决方法:一是调整逻辑,将列表长度小于等于2时清空列表;二是修改条件判断,避免使用`v-else`,确保每个条件独立判断。最后,作者建议使用Vue3以获得更好的性能和体验。
359 1
关于Vue2里 v-for和v-if一起用的时候会出现的问题
|
JavaScript
vue2中左侧菜单和头部tab标签联动
vue2中左侧菜单和头部tab标签联动
468 0
|
9月前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
10月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
118 1
vue学习第三章
|
10月前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
129 1
vue学习第十章(组件开发)
|
10月前
|
前端开发 JavaScript
使用 JavaScript 制作 To-Do List
本文详细介绍了如何使用HTML、CSS和JavaScript制作一个简单的To-Do List网页,包括添加、删除任务及标记任务完成等功能的实现,附带完整代码示例和页面样式设计。
226 1
使用 JavaScript 制作 To-Do List
|
10月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
114 1
vue学习第一章
|
9月前
|
存储 前端开发 UED
React 中的多选按钮(Checkbox)
本文详细介绍了在 React 中实现多选按钮(Checkbox)的方法,包括基础用法、常见问题及解决策略、进阶技巧如使用受控组件和第三方库,旨在帮助开发者更好地理解和应用多选按钮组件。
494 19
|
10月前
|
移动开发 前端开发 JavaScript
前端H5使用canvas画爱心以及笑脸
本文介绍了HTML5中的canvas元素及其基本用法,通过JavaScript在canvas上绘制图形。首先简述了canvas的功能,接着详细展示了如何使用`bezierCurveTo`方法绘制爱心和`arc`方法绘制笑脸,并附有示例代码及效果说明。最后总结了canvas在网页图形绘制上的应用潜力。
286 2

热门文章

最新文章