Browse Source

fix(tabbar): add props placeholder #1692 (#1796)

Drjingfubo 3 years ago
parent
commit
2073896d48

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

@@ -15,6 +15,7 @@ import { ActionSheet, Popup, OverLay } from '@nutui/nutui-taro';
 const app = createApp();
 app.use(ActionSheet);
 app.use(Popup);
+app.use(OverLay);
 ```
 
 ### Basic Usage

+ 1 - 0
src/packages/__VUE/actionsheet/doc.md

@@ -15,6 +15,7 @@ import { ActionSheet, Popup, OverLay } from '@nutui/nutui-taro';
 const app = createApp();
 app.use(ActionSheet);
 app.use(Popup);
+app.use(OverLay);
 ```
 
 ### 基础用法

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

@@ -185,6 +185,7 @@ If you need to use more icons based on the existing Icon, please refer to the Ic
 | unactive-color  | Color of unactive tab item  | string | #7d7e80 |
 | active-color    | Color of active tab item    | string | #1989fa |
 | safe-area-inset-bottom   | Whether to enable bottom safe area adaptation    | boolean | false |
+| placeholder `3.2.6` | Whether to generate a placeholder element when fixed | boolean | false |
 ### TabbarItem Props
 
 | Attribute      | Description                                      | Type   | Default |

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

@@ -240,6 +240,7 @@ app.use(TabbarItem);
 | to  `小程序不支持`      | 	标签页的路由对象,等于 vue-router 的 [to 属性](https://router.vuejs.org/zh/api/#to) 属性 | string|object | --     |
 | num       | 页签右上角的数字角标,超出99之后为99+     | number | --     |
 | dot       | 是否显示图标右上角小红点   | boolean | false    |
+| placeholder `3.2.6` | 固定在底部时,是否在标签位置生成一个等高的占位元素 | boolean | false |
 
 
 ### Tabbar Events

+ 35 - 3
src/packages/__VUE/tabbar/index.taro.vue

@@ -1,12 +1,26 @@
 <template>
-  <view class="nut-tabbar" :class="{ 'nut-tabbar-bottom': bottom, 'nut-tabbar-safebottom': safeAreaInsetBottom }">
+  <div v-if="bottom && placeholder" class="nut-tabbar__placeholder" :style="{ height: height + 'px' }">
+    <view
+      ref="nutTabbar"
+      class="nut-tabbar"
+      :class="{ 'nut-tabbar-bottom': bottom, 'nut-tabbar-safebottom': safeAreaInsetBottom }"
+    >
+      <slot></slot>
+    </view>
+  </div>
+  <view
+    v-else
+    class="nut-tabbar"
+    :class="{ 'nut-tabbar-bottom': bottom, 'nut-tabbar-safebottom': safeAreaInsetBottom }"
+  >
     <slot></slot>
   </view>
 </template>
 
 <script lang="ts">
-import { provide, reactive, watch } from 'vue';
+import { onMounted, provide, reactive, ref, toRefs, watch } from 'vue';
 import { createComponent } from '@/packages/utils/create';
+import Taro from '@tarojs/taro';
 const { create } = createComponent('tabbar');
 export default create({
   props: {
@@ -37,14 +51,20 @@ export default create({
     safeAreaInsetBottom: {
       type: Boolean,
       default: false
+    },
+    placeholder: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['tab-switch', 'update:visible'],
   setup(props, { emit, slots }) {
+    const { bottom, placeholder } = toRefs(props);
     const mdValue = reactive({
       val: props.visible,
       children: []
     });
+    const height = ref();
     function changeIndex(index: number, active: number | string) {
       emit('update:visible', active);
       parentData.modelValue = active;
@@ -65,8 +85,20 @@ export default create({
         parentData.modelValue = value;
       }
     );
+    onMounted(() => {
+      if (bottom.value && placeholder.value) {
+        setTimeout(() => {
+          const query = Taro.createSelectorQuery();
+          query.select('.nut-tabbar').boundingClientRect();
+          query.exec((res) => {
+            height.value = res[0].height;
+          });
+        }, 500);
+      }
+    });
     return {
-      changeIndex
+      changeIndex,
+      height
     };
   }
 });

+ 32 - 3
src/packages/__VUE/tabbar/index.vue

@@ -1,11 +1,24 @@
 <template>
-  <view class="nut-tabbar" :class="{ 'nut-tabbar-bottom': bottom, 'nut-tabbar-safebottom': safeAreaInsetBottom }">
+  <div v-if="bottom && placeholder" class="nut-tabbar__placeholder" :style="{ height: height + 'px' }">
+    <view
+      ref="nutTabbar"
+      class="nut-tabbar"
+      :class="{ 'nut-tabbar-bottom': bottom, 'nut-tabbar-safebottom': safeAreaInsetBottom }"
+    >
+      <slot></slot>
+    </view>
+  </div>
+  <view
+    v-else
+    class="nut-tabbar"
+    :class="{ 'nut-tabbar-bottom': bottom, 'nut-tabbar-safebottom': safeAreaInsetBottom }"
+  >
     <slot></slot>
   </view>
 </template>
 
 <script lang="ts">
-import { provide, reactive, watch } from 'vue';
+import { onMounted, provide, reactive, toRefs, ref, watch, nextTick } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { create } = createComponent('tabbar');
 export default create({
@@ -37,14 +50,21 @@ export default create({
     safeAreaInsetBottom: {
       type: Boolean,
       default: false
+    },
+    placeholder: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['tab-switch', 'update:visible'],
   setup(props, { emit, slots }) {
+    const { bottom, placeholder } = toRefs(props);
+    const height = ref();
     const mdValue = reactive({
       val: props.visible,
       children: []
     });
+    const nutTabbar = ref<HTMLElement | null>(null);
     function changeIndex(index: number, active: number | string) {
       emit('update:visible', active);
       parentData.modelValue = active;
@@ -65,9 +85,18 @@ export default create({
         parentData.modelValue = value;
       }
     );
+    onMounted(() => {
+      if (bottom.value && placeholder.value) {
+        nextTick(() => {
+          height.value = nutTabbar?.value?.getBoundingClientRect().height;
+        });
+      }
+    });
 
     return {
-      changeIndex
+      changeIndex,
+      nutTabbar,
+      height
     };
   }
 });