Vue下部ナビゲーションバーコンポーネント

将来のプロジェクトで簡単に使用できるように、下部のナビゲーションバー用に別のコンポーネントを作成します

ソースアドレス:https//github.com/michaelxuzhi/tabbar

作成とパッケージングの2つのステップに分かれています

要件:独立、アイコンの変更、名前の変更、フレックスレイアウト

①分析:最初はTabBarです

ここに画像の説明を挿入します

TabBarは、ナビゲーションバー全体をラップするナビゲーションバーのメインフレームです。

タブバーを作成-> Tabbar.vue

<template>
    <div id="tab-bar">
        // 这里啥都没有
    </div>
</template>

<script>
    export default {
     
     
        name: "Tabbar"
    }
</script>

<style scoped>
    #tab-bar {
     
     
        display: flex; /* 让后续所有的item都以flex摆放*//
        background-color: #f6f6f6;
	
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;

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

メインナビゲーションバー領域MainTabBar.vueを作成します。これは、実際にはナビゲーションバー領域Tabbar.vueを独立したコンポーネントに作成します。ナビゲーションバー領域でのTabBarItemの後続の実装により、すべてが抽出されたため、MainTabBarに表示されます。分離と独立。

MainTabBar.vue

<template>
    <tab-bar></tab-bar>
</template>

<script>
  import TabBar from "./tabbar/Tabbar";
 
  export default {
     
     
    name: "MainTabBar",
    components:{
     
     
      TabBar
    }
  }
</script>

<style scoped>

</style>

次に、App.vueでMainTabBarコンポーネントを参照します

<template>
  <div id="app">
    <main-tab-bar></main-tab-bar>
  </div>
</template>

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

これまで、下部のナビゲーションバー領域が作成されましたが、内部にコンテンツがないため、Tabbar.vueの高さは0であり、効果は見られません。Tabbar.vueのスタイルに少し高さを追加するだけです。 。ナビゲーションバー領域がどのように表示されるかはわかっています。このハードコードされた高さは後で削除され、ナビゲーションバーはTabBarItemのコンテンツによってサポートされます。

height: 50px;

ここに画像の説明を挿入します

②次に、各オプションであるTabBarItemを作成します

これらのオプションはTabbar.vueに挿入されるため、Tabbar.vueは、各アイテムを追加できるようにスロットを設定する必要があります。

<slot></slot>

ここに画像の説明を挿入します

tabbar-> TabbarItem.vue

ここに画像の説明を挿入します

Display:flexはナビゲーションバーに設定されています;ここではアイテムはflex:1に設定されています;アイテムの高さは通常のナビゲーションバーの高さである49pxに与えられます。高さがある場合はナビゲーションバーを開くことができ、アイテムのアイコンのスタイルを設定する必要があります。

<template>
    <div class="tab-bar-item" @click="itemClick">
    <!-- 这里要放图标和文字,会在后面继续新增 -->
    </div>
</template>

<script>
    export default {
     
     
      name: "TabbarItem",
      
      data(){
     
     
        return{
     
     },
      
      methods:{
     
     
          itemClick(){
     
     
              // 点击item会执行的操作
          }
      }
    }
</script>

<style scoped>
    .tab-bar-item {
     
     
        flex: 1;
        text-align: center;
        height: 49px;

        font-size: 14px;
    }

    .tab-bar-item img {
     
     
        margin-top: 3px;
        width: 24px;
        height: 24px;
        /* 去掉图片与文字之间的空隙 */
        vertical-align: middle;
        margin-bottom: 2px;
    }

</style>

アイテムにアイコンとテキストを挿入するために使用されます

アイテムアイコンの設定

<div class="tab-bar-item" @click="itemClick"> 
    
    
	<!-- 判断是否active,注意这里用的是取反 -->
	<div v-if="!isActive" slot="item-icon">
       <slot name="item-icon"></slot>
    </div>
    
    <div v-else slot="item-icon-active">
       <slot name="item-icon-active"></slot>
    </div>
    
    <!-- 这里还要放文字 -->
   
</div>

アイテムのテキスト設定

<div slot="item-text" :style="activeStyle">
   <slot name="item-text"></slot>
</div>

画像とテキストに名前付きスロットを使用する理由は、TabBarItemも分離された別個のコンポーネントであるためです。最終的に、TabBar.vueとTabBarItem.vueが参照され、MainTabBarに表示されます。

<template>
    <tab-bar>
        <!-- 这里是第一个item-首页 -->
        <!-- 给子页面传递path和activeColor参数 -->
        <tab-bar-item path="/home" activeColor="blue">
            <!-- 图片的路径自己插 -->
            <img slot="item-icon" src="@assets/img/tabbar/home.svg" alt="">
            <img slot="item-icon-active" src="@assets/img/tabbar/home_active.svg" alt="">
            <!-- 这是某一项的文字 -->
            <div slot="item-text">首页</div>
        </tab-bar-item>
        <!-- 这里是第二个item-分类 -->
        <tab-bar-item path="/category" activeColor="green">
            <img slot="item-icon" src="@assets/img/tabbar/category.svg" alt="">
            <img slot="item-icon-active" src="@assets/img/tabbar/category_active.svg" alt="">
            <div slot="item-text">分类</div>
        </tab-bar-item>
    </tab-bar>
</template>

<script>
  // 引用两个组件
  import TabBar from "./tabbar/Tabbar";
  import TabBarItem from "./tabbar/TabbarItem";
  export default {
     
     
    name: "MainTabBar",
    // 注册两个组件
    components:{
     
     
      TabBar,
      TabBarItem
    }
  }
</script>

<style scoped>

</style>

階層関係は次のとおりです。

img、text->tab-bar-item≈tab-bar-> main-tab-bar->アプリ

これらの2つのコンポーネントは、MainTabBar.vueで参照および使用され、パラメーターはサブレイヤーに渡されるため、propsを使用してサブレイヤーで受け取ります。

これはTabBarItemの論理処理です

<script>
    export default {
     
     
      name: "TabbarItem",
      props:{
     
     
        // 接收从MainTabBar传来的path和activeColor两个参数
        path: String,
        activeColor:{
     
     
          type:String,
          default : 'red'
        }
      },
      data(){
     
     
        return{
     
     
        }
      },
      computed : {
     
     
        // 判断一下是否被激活
        isActive() {
     
     
          return this.$route.path.indexOf(this.path) !== -1
        },
        // 被激活时的样式更改
        activeStyle() {
     
     
            return this.isActive ? {
     
     color : this.activeColor} : {
     
     }
        }
      },
      methods:{
     
     
        // 点击某个item,页面上显示对应页面
        itemClick(){
     
     
          this.$router.replace(this.path)
        }
      }
    }
</script>

コンポーネントの最終的な実現には、ナビゲーションバーに対応する各アイコンと対応する表示ページが必要です。

アイコンのパスはMainTabBar.vueで自分で変更します。対応する表示ページが必要な場合は、vue-routerをインストールして構成する必要があります。

これは、遅延読み込みと、対応する2つのページ「ホーム」と「カテゴリ」の単純な構成の組み合わせです。

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

// 引用两个要显示的页面的组件对应文件,使用的是懒加载
const Home = () => import('../views/home/Home');
const Category = () => import("../views/category/Category");

// 配置路由信息
const routes = [
  {
    
    
    path: '',
    redirect : '/home'
  },
  {
    
    
    path: '/home',
    component : Home
  },
  {
    
    
    path: '/category',
    component : Category
  }
]

// 使用的时'history'模式,
const router = new VueRouter({
    
    
  mode : 'history',
  routes
})

export default router

ついに実現

ここに画像の説明を挿入します

ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/michaelxuzhi___/article/details/105892928