Vue Tabbar 的封装

本文介绍了如何在Vue.js项目中创建和封装底部TabBar组件,包括步骤1的项目初始化,步骤2的组件拆分与样式设定,步骤3的Vue实例引用,以及步骤4的TabBar-Item组件事件监听和动态属性处理。通过这种方式,实现了底部导航栏的动态响应和页面跳转功能。
摘要由CSDN通过智能技术生成

Tabbar 的封装


1. 通过脚手架创建项目

  • 创建项目

    vue init webpack tabbar
    
  • 选择配置

    ? Project name vuecli2test # 会根据这个名称创建一个文件夹,存放之后项目的内容该名称也会作为默认的项目名称,但是不能包含大写字母等
    ? Project description description # 项目名称 , 不能有大写字母
    ? Author renyi <2822930767@qq.com>	# 作者信息
    ? Vue build standalone	# 后面介绍
    ? Install vue-router? Yes	# 路由
    ? Use ESLint to lint your code? Yes	# ESLint 代码规范检测, 根据自己需求
    ? Pick an ESLint preset Standard	
    ? Set up unit tests No	# 单元测试
    ? Setup e2e tests with Nightwatch? No	# e2e测试,end to end安装Nightwatch,是一个利用selenium或 webdrivers或phantomis等进行自动化测试的框架
    ? Should we run `npm install` for you after the project has been created? (recommended) npm # 选择npm 或 yarn
    

2. 项目搭建

  • 以下是项目框架 , 我们先将底部的导航抽取成一个 TaBra 组件 , 再将 其中的 4 个部分再抽取成一个 组件 Tabra-Item

  • 1. 创建 TaBra.vue

    • 创建TaBra.vue 后 , 在其模板中准备一个插槽 , 用于抽取 Tabra-Item
    <template>
      <div id="tab-bar">
        <!--这里的插槽是给Tabra-Iteam准备的-->
        <slot></slot>
      </div>
    </template>
    
    <script>
      export default {
        name: "TabBar"
      }
    </script>
    
    <style scoped>
      #tab-bar{
        display: flex;
        background-color: #f6f6f6;
    
        position: fixed;
        left: 0px;
        right: 0px;
        bottom: 0px;
    
        box-shadow: 0px -1px 1px rgba(144, 147, 145, 0.2);
      }
    </style>
    
  • 2. 抽取Tabra-Item

    在组件中提供3个插槽 , 一个是未获取焦点的图片 , 一个是获取焦点后的图片 , 还有一个是文本
    <template>
      <div class="tab-bar-item">
          <slot name="item-icon"></slot>
          <slot name="item-icon-active"></slot>
          <slot name="item-text"></slot>
      </div>
    </template>
    
    <script>
      export default {
        name: "TabBarItem",
      }
    </script>
    
    <style scoped>
    
      .tab-bar-item{
        flex: 1;
        text-align: center;
        height: 49px;
      }
    
      .tab-bar-item img{
        height: 24px;
        width: 24px;
      }
    
      .activeText{
        color: red;
      }
    
    </style>
    
    
  • 3. 在Vue.app中引用

    使用tab-bar-item组件 , 通过父传子将 path 和 activetext 传递到子组件 , 因为此处是固定的 , 不是一个变量 , 所以可以不动态绑定
    path: 跳转的路径
    activeText: Tabra-Item 选中后的 text 颜色
    <Tab-bar-item> 传递2个图片 , 一个是选中的 , 一个是未选中的 , 可以通过具名插槽在 Tabra-Item 组件中通过 v-if 来判断显示哪一个
    <template>
      <div id="app">
        <router-view></router-view>
        <!--使用tab-bar组件-->
        <tab-bar>
          <!--使用tab-bar-item组件 , 通过父传子将 path 和 activetext 传递到子组件 , 因为此处是固定的 , 不是一个变量 , 所以可以不动态绑定
    		path: 跳转的路径
    		activeText: Tabra-Item 选中后的 text 颜色
    		-->
          <tab-bar-item class="tab-bar-item" path="/home" activeText="red">
            <!--传递2个图片 , 一个是选中的 , 一个是未选中的 , 可以通过具名插槽在Tabra-Item中通过v-if来判断显示哪一个-->
            <img class="" slot="item-icon" src="./assets/img/tabbar/home.svg"/>
            <img class="" slot="item-icon-active" src="./assets/img/tabbar/home_active.svg"/>
            <div slot="item-text">首页</div>
          </tab-bar-item>
          <tab-bar-item class="tab-bar-item" path="/category" activeText="red">
            <img slot="item-icon" src="./assets/img/tabbar/category.svg"/>
            <img slot="item-icon-active" src="./assets/img/tabbar/category_active.svg"/>
            <div slot="item-text">分类</div>
          </tab-bar-item>
          <tab-bar-item class="tab-bar-item" path="/cart" activeText="red">
            <img slot="item-icon" src="./assets/img/tabbar/cart.svg"/>
            <img slot="item-icon-active" src="./assets/img/tabbar/cart_active.svg"/>
            <div slot="item-text">购物车</div>
          </tab-bar-item>
          <tab-bar-item class="tab-bar-item" path="/profile" activeText="red">
            <img slot="item-icon" src="./assets/img/tabbar/profile.svg"/>
            <img slot="item-icon-active" src="./assets/img/tabbar/profile_active.svg"/>
            <div slot="item-text">我的</div>
          </tab-bar-item>
        </tab-bar>
      </div>
    </template>
    
    <script>
    
    // 导入组件
    import TabBar from './components/tabbar/TabBar'
    import TabBarItem from './components/tabbar/TabBarItem'
    
    export default {
      name: 'App',
      components: { //注册组件
        TabBar,
        TabBarItem
      }
    }
    </script>
    
    <style>
    
    </style>
    
    
  • 4. 我们创建4个对应 Tabra-Item 的组件

    创建4个组件 , 分别是home category cart profile , 通过路由进行跳转 , 既然需要跳转 , 那么就需要监听事件 , 我们在 Tabra-Item 中进行监听
    我们通过 props 属性获取第3步所传入的 path 属性, 通过调用 this.$router.push(this.path); 进行跳转
    我们通过 isActive 函数来判断当前 Tabra-Item 是否处于选中状态 , 如果处于选中状态 , 我们就显示选中的图片也就是显示具名插槽 item-icon-active
    通过 setActiveText 函数设置 文本颜色 我们在第3步时传入了一个文本颜色 activeText 我们可以用 :style="setActiveText" 动态绑定 style 的方式从 setActiveText 函数获取到 css 样式
    <template>
      <div class="tab-bar-item" @click="ItemClick">
        <div v-if="!isActive">
          <slot name="item-icon"></slot>
        </div>
        <div v-else>
          <slot name="item-icon-active"></slot>
        </div>
         <div :style="setActiveText">
           <slot name="item-text"></slot>
         </div>
      </div>
    </template>
    
    <script>
      export default {
        name: "TabBarItem",
        props: {
          path : String,
          activeText:{
            type: String,
            default(){
              return "black"
            }
          }
        },
        data(){
          return {
            active: true
          }
        },
        computed: {
          isActive() {
            // 将route中的 path 和当前的path进行匹配
            return this.$route.path.indexOf(this.path) != -1
          },
          setActiveText() {
            // 如果处于激活状态 返回 color: this.activeText
            return this.isActive ? {color: this.activeText} : {color: "black"}
          }
        },
        methods: {
          ItemClick() {
            this.$router.push(this.path);
          }
        }
      }
    </script>
    
    <style scoped>
    
      .tab-bar-item{
        flex: 1;
        text-align: center;
        height: 49px;
      }
    
      .tab-bar-item img{
        height: 24px;
        width: 24px;
      }
    
      .activeText{
        color: red;
      }
    
    </style>
    
    
在 UniApp 中封装底部 Tabbar,你可以按照以下步骤进行操作: 1. 创建一个公共的 Tabbar 组件,可以使用 `uni-tabbar` 组件或者自定义组件实现。 2. 在 App.vue 文件中,使用 `<template>` 标签包裹 `<uni-tab-bar>` 组件,并设置 tabbar 的数据和事件处理方法。 3. 在每个页面的 vue 文件中,使用 `<template>` 标签包裹页面内容,并在相应的位置添加 `<uni-tab-bar-item>` 组件,设置对应的图标、标题和路径。 4. 在每个页面的 vue 文件中,在 `<script>` 标签中引入 tabbar 组件,并在 `data` 属性中定义 tabbar 的数据和事件处理方法。 5. 在组件的事件处理方法中,根据当前选中的 tabbar 项,通过 `uni.switchTab` 方法跳转到对应的页面。 下面是一个简单的示例: App.vue: ```vue <template> <view> <template> <uni-tab-bar :selected="selectedIndex" @click="switchTab"> <uni-tab-bar-item index="0" icon="home" text="首页" page="/pages/home"></uni-tab-bar-item> <uni-tab-bar-item index="1" icon="list" text="列表" page="/pages/list"></uni-tab-bar-item> <uni-tab-bar-item index="2" icon="user" text="我的" page="/pages/mine"></uni-tab-bar-item> </uni-tab-bar> </template> <router-view></router-view> </view> </template> <script> export default { data() { return { selectedIndex: 0 } }, methods: { switchTab(index) { this.selectedIndex = index uni.switchTab({ url: this.$children.$children[index].page }) } } } </script> ``` Home.vue: ```vue <template> <view> <!-- 页面内容 --> </view> </template> <script> import UniTabBarItem from '@/components/UniTabBarItem.vue' export default { components: { UniTabBarItem }, data() { return { tabbarData: [ { index: 0, icon: 'home', text: '首页', page: '/pages/home' }, { index: 1, icon: 'list', text: '列表', page: '/pages/list' }, { index: 2, icon: 'user', text: '我的', page: '/pages/mine' } ] } }, methods: { switchTab(index) { uni.switchTab({ url: this.tabbarData[index].page }) } } } </script> ``` List.vue 和 Mine.vue 的代码类似,只需要修改对应的页面内容和 tabbarData 数据。 这样,你就可以在页面中使用底部 Tabbar,并实现页面间的切换了。希望能对你有所帮助!如果还有其他问题,请随时提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值