Vue-cli3封装tabbar组件

tabbar组件

tabbarItem接收选项参数

  • 1.path(路由页面path)
    type:String
  • 2.selectedColor(选中文字颜色)
    type:String

1.tabbarItem.vue

<template>
  <div id="tabbar-item" @click="itemClick">
    <!-- 未选中图标 -->
    <div v-if="!isSelected">
      <slot name="item-icon">
        <img src="./../assets/imgs/home.svg" alt="" />
      </slot>
    </div>
    <!-- 选中图标 -->
    <div v-else>
      <slot name="item-icon-selected"></slot>
    </div>
    <!-- 文本内容 -->
    <div :style="selectedText">
      <slot name="item-text">文本</slot>
    </div>
  </div>
</template>

<script>
import { useRouter, useRoute } from "vue-router";
import { computed, onActivated } from "vue";
export default {
  name: "tabbarItem",
  // 选项接收的参数
  props: {
    path: String,
    selectedColor: {
      type: String,
      // 设置默认样式
      default: "orange",
    },
  },

  setup(props, context) {
    // 1.点击item-icon进行路由切换
    const router = useRouter();
    const itemClick = () => {
      router.push(props.path);
    };

    // 2.选项是否选中
    const route = useRoute();
    const isSelected = computed(() => {
      return route.path.includes(props.path);
    });

    // 3.处理选中的颜色
    const selectedText = computed(() => {
      if (isSelected.value) {
        return {
          color: props.selectedColor,
        };
      }
    });

    return {
      itemClick,
      isSelected,
      selectedText,
    };
  },
};
</script>

<style scoped>
#tabbar-item {
  flex: 1;
  height: 80px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  /* background-color: pink; */
}

.tab-bar-item img {
  width: 24px;
  height: 24px;
}

.selected {
  color: red;
}
</style>

2.tabbar.vue

<template >
  <div class="tab-bar">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "tabbar",
};
</script>

<style>
.tab-bar {
  background-color: #e6e6e6;
  /*固定定位*/
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  border-top: 1px solid #cccccc;
  /*伸缩布局*/
  display: flex;
}
</style>

3.router.js

import { createRouter, createWebHashHistory } from 'vue-router'

const Home = () => import('../pages/Home.vue')
const Course = () => import('../pages/Course.vue')
const About = () => import('../pages/About.vue')
const Mine = () => import('../pages/Mine.vue')

const routes = [
    { path: '/', redirect: '/home' },
    {
        path: '/home',
        component: Home,
        meta: {
            title: "主页"
        }
    },
    { path: '/course', component: Course },
    { path: '/about', component: About },
    { path: '/mine', component: Mine }
]

const router = createRouter({
    history: createWebHashHistory(),
    routes: routes,
})

export default router;

4.main.js

import { createApp } from 'vue'
import App from './App.vue'

// 引入全局路由对象
import router from "./router/index.js";

const app = createApp(App)
app.use(router)
app.mount('#app')

5.使用示例(App.vue)

<template>
  <div id="app">
    <tabbar>
      <tabbarItem path="/home" selectedColor="red">
        <!-- 图标 -->
        <template v-slot:item-icon>
          <img src="./assets/imgs/home.svg" alt="" />
        </template>
        <template v-slot:item-icon-selected>
          <img src="./assets/imgs/home_selected.svg" alt="" />
        </template>
        <!-- 标题 -->
        <template v-slot:item-text>
          <span>首页</span>
        </template>
      </tabbarItem>

      <tabbarItem path="/about">
        <!-- 图标 -->
        <template v-slot:item-icon>
          <img src="./assets/imgs/study.svg" alt="" />
        </template>
        <template v-slot:item-icon-selected>
          <img src="./assets/imgs/study_selected.svg" alt="" />
        </template>
        <!-- 标题 -->
        <template v-slot:item-text>
          <span>学习</span>
        </template>
      </tabbarItem>

      <tabbarItem path="/course">
        <!-- 图标 -->
        <template v-slot:item-icon>
          <img src="./assets/imgs/course.svg" alt="" />
        </template>
        <template v-slot:item-icon-selected>
          <img src="./assets/imgs/course_selected.svg" alt="" />
        </template>
        <!-- 标题 -->
        <template v-slot:item-text>
          <span>课程</span>
        </template>
      </tabbarItem>

      <tabbarItem path="/mine">
        <!-- 图标 -->
        <template v-slot:item-icon>
          <img src="./assets/imgs/mine.svg" alt="" />
        </template>
        <template v-slot:item-icon-selected>
          <img src="./assets/imgs/mine_selected.svg" alt="" />
        </template>
        <!-- 标题 -->
        <template v-slot:item-text>
          <span>我的</span>
        </template>
      </tabbarItem>
    </tabbar>
    <router-view></router-view>
  </div>
</template>


<script>
import tabbar from "./components/tabbar.vue";
import tabbarItem from "./components/tabbarItem.vue";
export default {
  name: "App",
  components: {
    tabbar,
    tabbarItem,
  },
};
</script>

<style>
/* 清除默认样式 */
html,
body {
  width: 100%;
  height: 100%;
}

#app {
  width: 100%;
  height: 100%;
}
</style>

6.效果

Vue-cli3封装tabbar组件

上一篇:vue-cli3构建的项目打包部署在非根目录下的服务器时需要进行的配置


下一篇:vue-cli3安装过程