Browse Source

fix(menu): 修改Menu弹出失效问题 (#1812)

* fix(menu): 修改Menu弹出失效问题

* fix(menu): 修复taro中menu闪跳问题
大胡子 3 years ago
parent
commit
7ce5c481f4

+ 13 - 20
src/packages/__VUE/menu/index.taro.vue

@@ -1,6 +1,6 @@
 <template>
   <view :class="classes">
-    <view class="nut-menu__bar" :class="{ opened: opened, 'offset-signal': offsetSignal }" ref="barRef">
+    <view :id="'nut-menu__bar' + refRandomId" class="nut-menu__bar" :class="{ opened: opened }" ref="barRef">
       <template v-for="(item, index) in children" :key="index">
         <view
           class="nut-menu__item"
@@ -27,6 +27,7 @@
 import { reactive, provide, computed, ref } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import Taro, { usePageScroll } from '@tarojs/taro';
+import { useTaroRect } from '@/packages/utils/useTaroRect';
 const { componentName, create } = createComponent('menu');
 export default create({
   props: {
@@ -64,6 +65,7 @@ export default create({
   },
   setup(props) {
     const barRef = ref<HTMLElement>();
+    const refRandomId = Math.random().toString(36).slice(-8);
     const offset = ref(0);
     const isScrollFixed = ref(false);
 
@@ -110,26 +112,17 @@ export default create({
       };
     });
 
-    // updateOffset 操作的标识位
-    // 解决 taro 下初次展开菜单栏闪跳问题 #1541
-    const offsetSignal = ref(false);
-
-    const updateOffset = (item) => {
+    const updateOffset = (children: any) => {
       if (barRef.value) {
-        offsetSignal.value = true;
         setTimeout(() => {
-          Taro.createSelectorQuery()
-            .select('.nut-menu__bar.offset-signal')
-            .boundingClientRect((rect) => {
-              if (props.direction === 'down') {
-                offset.value = rect.bottom;
-              } else {
-                offset.value = Taro.getSystemInfoSync().windowHeight - rect.top;
-              }
-              offsetSignal.value = false;
-              item.toggle();
-            })
-            .exec();
+          useTaroRect(barRef, Taro).then((rect: any) => {
+            if (props.direction === 'down') {
+              offset.value = rect.bottom;
+            } else {
+              offset.value = Taro.getSystemInfoSync().windowHeight - rect.top;
+            }
+            children.toggle();
+          });
         }, 100);
       }
     };
@@ -181,9 +174,9 @@ export default create({
       toggleItem,
       children,
       opened,
-      offsetSignal,
       classes,
       barRef,
+      refRandomId,
       getClasses
     };
   }

+ 12 - 3
src/packages/__VUE/menuitem/index.scss

@@ -36,14 +36,23 @@
   }
 }
 
-.nut-menu__overlay {
-  top: auto !important;
+.menu-item__pop-container {
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  right: 0;
+  left: 0;
+  overflow: hidden;
 }
 
 .nut-menu__pop {
   transition: all 0 ease 0;
   transform: none;
-  // top: auto !important;
+  position: absolute !important;
+}
+
+.nut-menu__overlay {
+  position: absolute !important;
 }
 
 .placeholder-element {

+ 6 - 7
src/packages/__VUE/menuitem/index.taro.vue

@@ -1,5 +1,5 @@
 <template>
-  <view :class="classes" v-show="state.showWrapper">
+  <view :class="classes" v-show="state.showWrapper" style="position: fixed" :style="{ zIndex: state.zIndex }">
     <div
       v-show="state.isShowPlaceholderElement"
       @click="handleClickOutside"
@@ -9,10 +9,8 @@
     >
     </div>
     <nut-popup
-      :style="
-        parent.props.direction === 'down' ? { top: parent.offset.value + 'px' } : { bottom: parent.offset.value + 'px' }
-      "
-      :overlayStyle="
+      class="menu-item__pop-container"
+      :containerStyle="
         parent.props.direction === 'down' ? { top: parent.offset.value + 'px' } : { bottom: parent.offset.value + 'px' }
       "
       v-bind="$attrs"
@@ -20,7 +18,6 @@
       :position="parent.props.direction === 'down' ? 'top' : 'bottom'"
       :duration="parent.props.duration"
       pop-class="nut-menu__pop"
-      transition="transition-none"
       overlayClass="nut-menu__overlay"
       :overlay="parent.props.overlay"
       :lockScroll="parent.props.lockScroll"
@@ -68,7 +65,7 @@ import { createComponent } from '@/packages/utils/create';
 const { componentName, create } = createComponent('menu-item');
 import Icon from '../icon/index.taro.vue';
 import Popup from '../popup/index.taro.vue';
-
+let _zIndex = 2000;
 export default create({
   props: {
     title: String,
@@ -99,6 +96,7 @@ export default create({
   emits: ['update:modelValue', 'change'],
   setup(props, { emit, slots }) {
     const state = reactive({
+      zIndex: _zIndex,
       showPopup: false,
       transition: true,
       showWrapper: false,
@@ -153,6 +151,7 @@ export default create({
 
       if (show) {
         state.showWrapper = true;
+        state.zIndex = ++_zIndex;
       }
     };
 

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

@@ -207,6 +207,7 @@ app.use(OverLay)
 | close-on-click-overlay | 是否点击遮罩关闭                                            | Boolean        | `true`        |
 | position               | 弹出位置(top,bottom,left,right,center)                    | String         | `"center"`    |
 | transition             | 动画名                                                      | String         | -             |
+| container-style        | 自定义外层容器样式                                          | CSSProperties  | -             |
 | style                  | 自定义弹框样式                                              | CSSProperties  | -             |
 | pop-class              | 自定义弹框类名                                              | String         | -             |
 | closeable              | 是否显示关闭按钮                                            | Boolean        | `false`        |

+ 4 - 1
src/packages/__VUE/popup/index.taro.vue

@@ -1,5 +1,5 @@
 <template>
-  <view :catch-move="lockScroll">
+  <view :catch-move="lockScroll" :style="containerStyle">
     <nut-overlay
       v-if="overlay"
       :visible="visible"
@@ -55,6 +55,9 @@ export const popupProps = {
     default: 'center'
   },
   transition: String,
+  containerStyle: {
+    type: Object as PropType<CSSProperties>
+  },
   style: {
     type: Object as PropType<CSSProperties>
   },