Drjingfubo 5 年 前
コミット
255b00f7ee

+ 9 - 0
src/config.js

@@ -237,6 +237,15 @@ module.exports = {
           show: true,
           desc: '标签组件',
           author: 'zhenyulei'
+        },
+        {
+          name: 'tabbar',
+          sort: 2,
+          cName: '标签栏组件',
+          type: 'component',
+          show: true,
+          desc: '标签栏组件',
+          author: 'Drjingfubo'
         }
       ]
     },

+ 155 - 0
src/packages/tabbar/demo.vue

@@ -0,0 +1,155 @@
+<template>
+  <div class="demo">
+    <h2>基础用法</h2>
+    <nut-tabbar :tab-List="tabList" @tab-switch="tabSwitch"></nut-tabbar>
+
+    <h2>徽标提示</h2>
+    <nut-tabbar :tab-List="tabList1" @tab-switch="tabSwitch"></nut-tabbar>
+
+    <h2>自定义颜色</h2>
+    <nut-tabbar
+      unactiveColor="#7d7e80"
+      activeColor="#1989fa"
+      :tab-List="tabList"
+      @tab-switch="tabSwitch"
+    ></nut-tabbar>
+    <h2>三个icon的tabbar</h2>
+    <nut-tabbar
+      unactiveColor="#7d7e80"
+      activeColor="#1989fa"
+      :tab-List="tabList2"
+      @tab-switch="tabSwitch"
+    ></nut-tabbar>
+    <h2>固定底部,可自由跳转</h2>
+    <nut-tabbar
+      :tab-List="tabList3"
+      @tab-switch="tabSwitch"
+      :bottom="true"
+    ></nut-tabbar>
+  </div>
+</template>
+
+<script lang="ts">
+import { ref, reactive, toRefs } from 'vue';
+import { createComponent } from '@/utils/create';
+const { createDemo } = createComponent('tabbar');
+export default createDemo({
+  props: {},
+  setup() {
+    const tabList = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home'
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category'
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find'
+      },
+      {
+        tabTitle: '购物车',
+        curr: false,
+        icon: 'cart'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my'
+      }
+    ];
+    const tabList1 = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home'
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category'
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find'
+      },
+      {
+        tabTitle: '购物车',
+        curr: true,
+        icon: 'cart',
+        num: '12'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my'
+      }
+    ];
+    const tabList2 = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home'
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my'
+      }
+    ];
+    const tabList3 = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home'
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category'
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find'
+      },
+      {
+        tabTitle: '购物车',
+        curr: false,
+        icon: 'cart',
+        num: '122'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my'
+      }
+    ];
+    function tabSwitch(item: object, index: number) {
+      console.log(item, index);
+    }
+    return {
+      ...reactive({
+        tabList,
+        tabList1,
+        tabList2,
+        tabList3
+      }),
+      tabSwitch
+    };
+  }
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 258 - 0
src/packages/tabbar/doc.md

@@ -0,0 +1,258 @@
+# Tabbar 列表组件
+
+### 介绍
+
+XXXXXX
+### 安装
+
+``` javascript
+import { createApp } from 'vue';
+import { Tabbar } from '@nutui/nutui';
+
+const app = createApp();
+app.use(Tabbar);
+
+```
+
+## 代码示例
+
+### 基础用法
+
+``` html
+<nut-tabbar :tab-List="tabList" @tab-switch="tabSwitch"></nut-tabbar>
+```
+
+``` javascript
+// ...
+  setup() {
+    const tabList = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home',
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category',
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find',
+      },
+      {
+        tabTitle: '购物车',
+        curr: false,
+        icon: 'cart',
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my',
+      },
+    ];
+    function tabSwitch(item: object, index: number) {
+      console.log(item, index);
+    }
+    return {
+      ...reactive({
+        tabList,
+      }),
+      tabSwitch,
+    };
+  },
+// ...
+```
+
+### 徽标提示
+
+``` html
+<nut-tabbar :tab-List="tabList" @tab-switch="tabSwitch"></nut-tabbar>
+```
+
+``` javascript
+// ...
+  setup() {
+    const tabList = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home',
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category',
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find',
+      },
+      {
+        tabTitle: '购物车',
+        curr: false,
+        icon: 'cart',
+        num: '12'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my',
+      },
+    ];
+    function tabSwitch(item: object, index: number) {
+      console.log(item, index);
+    }
+    return {
+      ...reactive({
+        tabList,
+      }),
+      tabSwitch,
+    };
+  },
+// ...
+```
+
+### 自定义颜色
+
+``` html
+<nut-tabbar :tab-List="tabList" @tab-switch="tabSwitch"></nut-tabbar>
+```
+
+``` javascript
+// ...
+  setup() {
+    const tabList = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home',
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category',
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find',
+      },
+      {
+        tabTitle: '购物车',
+        curr: false,
+        icon: 'cart',
+        num: '12'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my',
+      },
+    ];
+    function tabSwitch(item: object, index: number) {
+      console.log(item, index);
+    }
+    return {
+      ...reactive({
+        tabList,
+      }),
+      tabSwitch,
+    };
+  },
+// ...
+```
+
+### 三个图标的标签栏
+
+``` html
+<nut-tabbar :tab-List="tabList" @tab-switch="tabSwitch"></nut-tabbar>
+```
+
+``` javascript
+// ...
+  setup() {
+        const tabList = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home'
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my'
+      }
+    ];
+    function tabSwitch(item: object, index: number) {
+      console.log(item, index);
+    }
+    return {
+      ...reactive({
+        tabList,
+      }),
+      tabSwitch,
+    };
+  },
+// ...
+```
+
+### 固定底部,可自由跳转
+
+``` html
+<nut-tabbar :tab-List="tabList" @tab-switch="tabSwitch" :bottom="true" ></nut-tabbar>
+```
+
+``` javascript
+// ...
+  setup() {
+        const tabList = [
+      {
+        tabTitle: '首页',
+        curr: false,
+        icon: 'home'
+      },
+      {
+        tabTitle: '分类',
+        curr: false,
+        icon: 'category'
+      },
+      {
+        tabTitle: '发现',
+        curr: false,
+        icon: 'find'
+      },
+      {
+        tabTitle: '购物车',
+        curr: false,
+        icon: 'cart',
+        num: '122'
+      },
+      {
+        tabTitle: '我的',
+        curr: false,
+        icon: 'my'
+      }
+    ];
+    function tabSwitch(item: object, index: number) {
+      console.log(item, index);
+    }
+    return {
+      ...reactive({
+        tabList,
+      }),
+      tabSwitch,
+    };
+  },
+// ...
+```
+
+
+

+ 91 - 0
src/packages/tabbar/index.scss

@@ -0,0 +1,91 @@
+.nut-tabbar {
+  border: 0px;
+  border-bottom: 1px solid #eee;
+  border-top: 1px solid #eee;
+  width: 100%;
+  display: flex;
+  height: 50px;
+  box-sizing: border-box;
+  background: #fff;
+
+  &:last-child {
+    border-right: 0;
+  }
+}
+
+.bottom {
+  position: fixed;
+  bottom: 0px;
+  left: 0px;
+  z-index: 888;
+}
+
+.tabbar-nav {
+  flex: 1;
+  text-align: center;
+  text-decoration: none;
+  color: $text-color;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.card {
+  border-right: 1px solid #eee;
+}
+
+// .curr {
+//   color: $primary-color;
+// }
+
+.icon-box {
+  padding: 0px;
+  display: inline-block;
+  position: relative;
+
+  .tips {
+    position: absolute;
+    background: rgba(250, 44, 25, 1);
+    border: 1px solid rgba(255, 255, 255, 1);
+    border-radius: 7px;
+    text-align: center;
+
+    top: -2px;
+    right: -7px;
+    box-shadow: 0 0 0 1px #fff;
+    font-size: $font-size-1;
+    color: #fff;
+  }
+
+  .num {
+    line-height: 11px;
+    font-family: PingFangSC-Regular;
+    font-size: 11px;
+    color: rgba(255, 255, 255, 1);
+    padding: 1px 2px 2px 3px;
+  }
+  .nums {
+    line-height: 10px;
+    font-family: PingFangSC-Regular;
+    font-size: 10px;
+    color: rgba(255, 255, 255, 1);
+    padding: 2px 1px 2px 2px;
+  }
+}
+
+.icon-box .icon {
+  display: block;
+  background-size: 100% 100%;
+  background-position: center center;
+}
+
+.icon-box .tabbar-nav-word {
+  font-size: 10px;
+  display: block;
+}
+
+.icon-box .big-word {
+  font-size: 16px;
+  line-height: 1;
+}

+ 103 - 0
src/packages/tabbar/index.vue

@@ -0,0 +1,103 @@
+<template>
+  <view class="nut-tabbar" :class="{ bottom: bottom }">
+    <view
+      class="tabbar-nav"
+      v-for="(item, index) in tabList"
+      :key="index"
+      :style="{ color: index == currIndex ? activeColor : unactiveColor }"
+      :class="type"
+      @click="switchTabs(item, index)"
+    >
+      <view class="icon-box">
+        <view class="tips num" v-if="item.num && item.num <= 99">
+          {{ item.num }}
+        </view>
+        <view class="tips nums" v-else-if="item.num && item.num > 100">{{
+          '99+'
+        }}</view>
+        <view v-if="item.icon">
+          <nut-icon class="icon" :size="size" :name="item.icon"></nut-icon>
+        </view>
+        <view :class="['tabbar-nav-word', { 'big-word': !item.icon }]">{{
+          item.tabTitle
+        }}</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script lang="ts">
+import { ref, onMounted } from 'vue';
+import { createComponent } from '@/utils/create';
+const { create } = createComponent('tabbar');
+type obj = {
+  tabTitle: string;
+  curr: boolean;
+  icon: string;
+  href: string;
+  color: string;
+};
+export default create({
+  props: {
+    tabList: {
+      type: Array,
+      default: () => {
+        return [];
+      }
+    },
+    bottom: {
+      type: Boolean,
+      default: false
+    },
+    type: {
+      type: String,
+      default: 'base'
+    },
+    size: {
+      type: String,
+      default: '20px'
+    },
+    unactiveColor: {
+      type: String,
+      default: '#000000'
+    },
+    activeColor: {
+      type: String,
+      default: '#fa2c19'
+    }
+  },
+  components: {},
+  setup(props, { emit }) {
+    console.log(props);
+    const currIndex: any = ref(0);
+    const { tabList } = props;
+    function initbar() {
+      tabList.forEach((item: any, index) => {
+        if (item.curr) {
+          currIndex.value = index;
+        }
+      });
+    }
+    // 点击以后切换
+    function switchTabs(item: obj, index: number) {
+      currIndex.value = index;
+      if (item.href) {
+        window.location.href = item.href;
+      }
+      emit('tab-switch', item, index);
+    }
+    onMounted(() => {
+      initbar();
+    });
+    return {
+      currIndex,
+      tabList,
+      switchTabs
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>