ソースを参照

fix: tabbar增加name匹配

Drjnigfubo 3 年 前
コミット
619e7c208f

+ 4 - 6
src/packages/__VUE/circleprogress/index.taro.vue

@@ -114,17 +114,15 @@ export default create({
       };
     });
     const format = (progress: string | number) => Math.min(Math.max(+progress, 0), 100);
-    const requestAnimationFrame = function (callback: Function, lastTime: any) {
-      var lastTime;
-      if (typeof lastTime === 'undefined') {
-        lastTime = 0;
-      }
+    var lastTime = 0;
+    const requestAnimationFrame = function (callback: Function) {
       var currTime = new Date().getTime();
       var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
       lastTime = currTime + timeToCall;
       var id = setTimeout(function () {
         callback(currTime + timeToCall, lastTime);
       }, timeToCall);
+      lastTime = currTime + timeToCall;
       return id;
     };
 
@@ -147,7 +145,7 @@ export default create({
           currentRate.value = Math.min(Math.max(+rate, 0), 100);
           emit('update:progress', format(parseFloat(rate.toFixed(1))));
           if (endRate > startRate ? rate < endRate : rate > endRate) {
-            rafId = requestAnimationFrame(animate, 0);
+            rafId = requestAnimationFrame(animate);
           }
         };
         if (rafId) {

+ 13 - 0
src/packages/__VUE/tabbar/demo.vue

@@ -9,6 +9,15 @@
       <nut-tabbar-item :tab-title="translate('title')" icon="cart"></nut-tabbar-item>
       <nut-tabbar-item :tab-title="translate('title')" icon="my"></nut-tabbar-item>
     </nut-tabbar>
+    <h2>{{ translate('byName') }}</h2>
+
+    <nut-tabbar @tab-switch="tabSwitch" v-model:visible="activeName">
+      <nut-tabbar-item name="home" :tab-title="translate('title')" icon="home"></nut-tabbar-item>
+      <nut-tabbar-item name="category" :tab-title="translate('title')" icon="category"></nut-tabbar-item>
+      <nut-tabbar-item name="find" :tab-title="translate('title')" icon="find"></nut-tabbar-item>
+      <nut-tabbar-item name="cart" :tab-title="translate('title')" icon="cart"></nut-tabbar-item>
+      <nut-tabbar-item name="my" :tab-title="translate('title')" icon="my"></nut-tabbar-item>
+    </nut-tabbar>
     <h2>{{ translate('customImg') }}</h2>
 
     <nut-tabbar @tab-switch="tabSwitch">
@@ -90,6 +99,7 @@ import { useTranslate } from '@/sites/assets/util/useTranslate';
 useTranslate({
   'zh-CN': {
     basic: '基本用法',
+    byName: '通过名称匹配',
     customImg: '自定义图片',
     customCheck: '自定义选中',
     showBadge: '徽标提示',
@@ -100,6 +110,7 @@ useTranslate({
   },
   'en-US': {
     basic: 'Basic Usage',
+    byName: 'Match by name',
     customImg: 'Custom Img',
     customCheck: 'Custom Check',
     showBadge: 'Show Badge',
@@ -113,11 +124,13 @@ export default createDemo({
   props: {},
   setup() {
     const active = ref(2);
+    const activeName = ref('category');
     function tabSwitch(item: Record<string, unknown>, index: number) {
       console.log(item, index);
     }
     return {
       active,
+      activeName,
       tabSwitch,
       translate
     };

+ 1 - 0
src/packages/__VUE/tabbar/doc.en-US.md

@@ -190,6 +190,7 @@ If you need to use more icons based on the existing Icon, please refer to the Ic
 | Attribute      | Description                                      | Type   | Default |
 |-----------|-------------------------------------------|--------|--------|
 | tab-title | title                              | string | --     |
+| name | Identifier                              | string | 	Item index     |
 | icon      | icon name   | string | --     |
 | font-class-name |Custom icon font base class name    | string           | `nutui-iconfont` |
 | class-prefix | Custom icon class name prefix for using custom icons     | string           | `nut-icon` |

+ 45 - 1
src/packages/__VUE/tabbar/doc.md

@@ -47,6 +47,35 @@ app.use(TabbarItem);
 ```
 :::
 
+### 通过名称匹配
+
+:::demo
+```html
+<template>
+  <nut-tabbar @tab-switch="tabSwitch"  v-model:visible="activeName">
+    <nut-tabbar-item tab-title="首页" name="home" icon="home"></nut-tabbar-item>
+    <nut-tabbar-item tab-title="分类" name="category" icon="category"></nut-tabbar-item>
+    <nut-tabbar-item tab-title="发现" name="find" icon="find"></nut-tabbar-item>
+    <nut-tabbar-item tab-title="购物车" name="cart" icon="cart"></nut-tabbar-item>
+    <nut-tabbar-item tab-title="我的" name="my" icon="my"></nut-tabbar-item>
+  </nut-tabbar>
+</template>
+<script>
+  export default{
+    setup() {
+      const activeName = ref("category");
+      function tabSwitch(item, index) {
+        console.log(item, index);
+      }
+      return {
+        tabSwitch,
+        activeName,
+      };
+    },
+  }
+</script>
+```
+:::
 
 ### 自定义图片链接
 :::demo
@@ -107,6 +136,20 @@ app.use(TabbarItem);
     <nut-tabbar-item tab-title="我的" icon="my"></nut-tabbar-item>
   </nut-tabbar>
 </template>
+<script>
+  export default{
+    setup() {
+      const active = ref(2);
+      function tabSwitch(item, index) {
+        console.log(item, index);
+      }
+      return {
+        tabSwitch,
+        activeName,
+      };
+    },
+  }
+</script>
 ```
 :::
 ### 徽标提示
@@ -186,7 +229,8 @@ app.use(TabbarItem);
 
 | 字段      | 说明                                      | 类型   | 默认值 |
 |-----------|-------------------------------------------|--------|--------|
-| tab-title | 标签页的标题                              | string | --     |
+| tab-title | 标签页的标题                              | string | --    |
+| name| 标签名称,作为匹配的标识符                             | string | 当前标签的索引值   |
 | icon      | 标签页显示的[图标名称](#/icon)  | string | --     |
 | font-class-name | 自定义icon 字体基础类名     | string           | `nutui-iconfont` |
 | class-prefix | 自定义icon 类名前缀,用于使用自定义图标     | string           | `nut-icon` |

+ 2 - 2
src/packages/__VUE/tabbar/index.taro.vue

@@ -45,10 +45,10 @@ export default create({
       val: props.visible,
       children: []
     });
-    function changeIndex(active: number) {
+    function changeIndex(index: number, active: any) {
       emit('update:visible', active);
       parentData.modelValue = active;
-      emit('tab-switch', parentData.children[active], active);
+      emit('tab-switch', parentData.children[index], active);
     }
     let parentData = reactive({
       children: mdValue.children,

+ 2 - 2
src/packages/__VUE/tabbar/index.vue

@@ -45,10 +45,10 @@ export default create({
       val: props.visible,
       children: []
     });
-    function changeIndex(active: number) {
+    function changeIndex(index: number, active: any) {
       emit('update:visible', active);
       parentData.modelValue = active;
-      emit('tab-switch', parentData.children[active], active);
+      emit('tab-switch', parentData.children[index], active);
     }
     let parentData = reactive({
       children: mdValue.children,

+ 28 - 9
src/packages/__VUE/tabbaritem/index.taro.vue

@@ -1,9 +1,9 @@
 <template>
   <div
     class="nut-tabbar-item"
-    :class="{ 'nut-tabbar-item__icon--unactive': state.active != state.index }"
+    :class="{ 'nut-tabbar-item__icon--unactive': !active }"
     :style="{
-      color: state.active == state.index ? state.activeColor : state.unactiveColor
+      color: active ? state.activeColor : state.unactiveColor
     }"
     @click="change(state.index)"
   >
@@ -32,7 +32,7 @@
         v-if="!icon && activeImg"
         class="nut-tabbar-item_icon-box_icon"
         :style="{
-          backgroundImage: `url(${state.active == state.index ? activeImg : img})`,
+          backgroundImage: `url(${active ? activeImg : img})`,
           width: state.size,
           height: state.size
         }"
@@ -57,6 +57,9 @@ export default create({
       type: String,
       default: ''
     },
+    name: {
+      type: String
+    },
     icon: {
       // 标签页显示的icon
       type: String,
@@ -105,15 +108,24 @@ export default create({
     });
     const relation = (child: ComponentInternalInstance): void => {
       if (child.proxy) {
-        let index = parent.children.length;
-        state.index = index;
         parent.children.push(child.proxy);
+        const index = computed(() => parent.children.indexOf(child.proxy));
+        state.index = props.name ?? index.value;
       }
     };
     relation(getCurrentInstance() as ComponentInternalInstance);
-    function change(index: Number) {
-      parent.changeIndex(index);
+    const active = computed(() => state.index === state.active);
+    function change() {
+      let key = props.name ?? state.index;
+      let index = null;
+      if (props.name) {
+        index = parent.children.findIndex((item: any) => {
+          return item.name == key;
+        });
+      }
+      parent.changeIndex(index ?? key, state.index);
     }
+
     const choosed = computed(() => {
       if (parent) {
         return parent.modelValue;
@@ -122,14 +134,21 @@ export default create({
     });
     watch(choosed, (value, oldValue) => {
       state.active = value;
+      let index = value;
+      if (props.name) {
+        index = parent.children.findIndex((item: any) => {
+          return item.name == value;
+        });
+      }
       setTimeout(() => {
-        if (parent.children[value].href) {
-          window.location.href = parent.children[value].href;
+        if (parent.children[index].href) {
+          window.location.href = parent.children[index].href;
         }
       });
     });
     return {
       state,
+      active,
       change
     };
   }

+ 31 - 12
src/packages/__VUE/tabbaritem/index.vue

@@ -1,11 +1,11 @@
 <template>
   <div
     class="nut-tabbar-item"
-    :class="{ 'nut-tabbar-item__icon--unactive': state.active != state.index }"
+    :class="{ 'nut-tabbar-item__icon--unactive': !active }"
     :style="{
-      color: state.active == state.index ? state.activeColor : state.unactiveColor
+      color: active ? state.activeColor : state.unactiveColor
     }"
-    @click="change(state.index)"
+    @click="change()"
   >
     <view class="nut-tabbar-item_icon-box">
       <template v-if="!dot">
@@ -33,7 +33,7 @@
         v-if="!icon && activeImg"
         class="nut-tabbar-item_icon-box_icon"
         :style="{
-          backgroundImage: `url(${state.active == state.index ? activeImg : img})`,
+          backgroundImage: `url(${active ? activeImg : img})`,
           width: state.size,
           height: state.size
         }"
@@ -59,6 +59,9 @@ export default create({
       type: String,
       default: ''
     },
+    name: {
+      type: String
+    },
     icon: {
       // 标签页显示的icon
       type: String,
@@ -108,14 +111,23 @@ export default create({
     const router = useRouter();
     const relation = (child: ComponentInternalInstance): void => {
       if (child.proxy) {
-        let index = parent.children.length;
-        state.index = index;
         parent.children.push(child.proxy);
+        const index = computed(() => parent.children.indexOf(child.proxy));
+        state.index = props.name ?? index.value;
       }
     };
     relation(getCurrentInstance() as ComponentInternalInstance);
-    function change(index: Number) {
-      parent.changeIndex(index);
+    const active = computed(() => state.index === state.active);
+
+    function change() {
+      let key = props.name ?? state.index;
+      let index = null;
+      if (props.name) {
+        index = parent.children.findIndex((item: any) => {
+          return item.name == key;
+        });
+      }
+      parent.changeIndex(index ?? key, state.index);
     }
     const choosed = computed(() => {
       if (parent) {
@@ -125,13 +137,19 @@ export default create({
     });
     watch(choosed, (value, oldValue) => {
       state.active = value;
+      let index = value;
+      if (props.name) {
+        index = parent.children.findIndex((item: any) => {
+          return item.name == value;
+        });
+      }
       setTimeout(() => {
-        if (parent.children[value].href) {
-          window.location.href = parent.children[value].href;
+        if (parent.children[index].href) {
+          window.location.href = parent.children[index].href;
           return;
         }
-        if (parent.children[value].to) {
-          let to = parent.children[value].to;
+        if (parent.children[index].to) {
+          let to = parent.children[index].to;
           if (to && router) {
             router.push(to);
           } else {
@@ -142,6 +160,7 @@ export default create({
     });
     return {
       state,
+      active,
       change
     };
   }

+ 7 - 7
src/sites/mobile-taro/vue/src/nav/pages/tabbar/index.vue

@@ -37,12 +37,12 @@
       ></nut-tabbar-item>
     </nut-tabbar>
     <h2>自定义选中</h2>
-    <nut-tabbar v-model:visible="active">
-      <nut-tabbar-item tab-title="首页" icon="home"></nut-tabbar-item>
-      <nut-tabbar-item tab-title="分类" icon="category"></nut-tabbar-item>
-      <nut-tabbar-item tab-title="发现" icon="find"></nut-tabbar-item>
-      <nut-tabbar-item tab-title="购物车" icon="cart"></nut-tabbar-item>
-      <nut-tabbar-item tab-title="我的" icon="my"></nut-tabbar-item>
+    <nut-tabbar v-model:visible="active" @tab-switch="tabSwitch">
+      <nut-tabbar-item tab-title="首页" name="home" icon="home"></nut-tabbar-item>
+      <nut-tabbar-item tab-title="分类" name="home1" icon="category"></nut-tabbar-item>
+      <nut-tabbar-item tab-title="发现" name="home2" icon="find"></nut-tabbar-item>
+      <nut-tabbar-item tab-title="购物车" name="home3" icon="cart"></nut-tabbar-item>
+      <nut-tabbar-item tab-title="我的" name="home4" icon="my"></nut-tabbar-item>
     </nut-tabbar>
 
     <h2>徽标提示</h2>
@@ -84,7 +84,7 @@ import { ref } from 'vue';
 export default {
   props: {},
   setup() {
-    const active = ref(2);
+    const active = ref('home1');
     function tabSwitch(item: object, index: number) {
       console.log(item, index);
     }