ソースを参照

fix: 解决popup组价destroyOnClose失效问题

杨凯旋 5 年 前
コミット
c9195247f8

+ 32 - 139
src/packages/popup/demo.vue

@@ -1,138 +1,46 @@
 <template>
-  <div>
-    <h2 class="title">基本用法</h2>
+  <div class="demo-list">
+    <h4>基本用法</h4>
     <div>
-        <nut-cell
-        isLink
-        title="展示弹出层"
-        :showIcon="true"
-        @click.native="showBasic = true"
-        >
-        </nut-cell>
+      <nut-cell isLink title="展示弹出层" :showIcon="true" @click.native="showBasic = true"> </nut-cell>
     </div>
-    <nut-popup :style="{ padding: '30px 50px' }"   v-model="showBasic" >正文</nut-popup>
+    <nut-popup :style="{ padding: '30px 50px' }" v-model="showBasic">正文</nut-popup>
 
-    <h2 class="title">弹出位置</h2>
+    <h4>弹出位置</h4>
     <div>
-        <nut-cell
-        isLink
-        title="顶部弹出"
-        :showIcon="true"
-        @click.native="showTop = true"
-        >
-        </nut-cell>
-        <nut-popup position="top" v-model="showTop" :style="{ height: '20%' }">
-        </nut-popup>
-        <nut-cell
-        isLink
-        title="底部弹出"
-        :showIcon="true"
-        @click.native="showBottom = true"
-        >
-        </nut-cell>
-        <nut-popup
-        v-model="showBottom"
-        position="bottom"
-        :style="{ height: '20%' }"
-        >
-        </nut-popup>
-        <nut-cell
-        isLink
-        title="左侧弹出"
-        :showIcon="true"
-        @click.native="showLeft = true"
-        >
-        </nut-cell>
-        <nut-popup
-        :style="{ width: '20%', height: '100%' }"
-        v-model="showLeft"
-        position="left"
-        ></nut-popup>
-        <nut-cell
-        isLink
-        title="右侧弹出"
-        :showIcon="true"
-        @click.native="showRight = true"
-        >
-        </nut-cell>
-        <nut-popup
-        position="right"
-        v-model="showRight"
-        :style="{ width: '20%', height: '100%' }"
-        ></nut-popup>
+      <nut-cell isLink title="顶部弹出" :showIcon="true" @click.native="showTop = true"> </nut-cell>
+      <nut-popup position="top" v-model="showTop" :style="{ height: '20%' }"> </nut-popup>
+      <nut-cell isLink title="底部弹出" :showIcon="true" @click.native="showBottom = true"> </nut-cell>
+      <nut-popup v-model="showBottom" position="bottom" :style="{ height: '20%' }"> </nut-popup>
+      <nut-cell isLink title="左侧弹出" :showIcon="true" @click.native="showLeft = true"> </nut-cell>
+      <nut-popup :style="{ width: '20%', height: '100%' }" v-model="showLeft" position="left"></nut-popup>
+
+      <nut-popup position="right" v-model="showRight" :style="{ width: '20%', height: '100%' }"></nut-popup>
+      <nut-cell isLink title="右侧弹出" :showIcon="true" @click.native="showRight = true"> </nut-cell>
     </div>
-    <h2 class="title">关闭图标</h2>
+    <h4>关闭图标</h4>
     <div>
-        <nut-cell
-        isLink
-        title="关闭图标"
-        :showIcon="true"
-        @click.native="showIcon = true">
-        </nut-cell>
-        <nut-popup
-        position="bottom"
-        closeable 
-        v-model="showIcon"
-        :style="{ height: '20%' }"
-        ></nut-popup>
+      <nut-cell isLink title="关闭图标" :showIcon="true" @click.native="showIcon = true"> </nut-cell>
+      <nut-popup position="bottom" closeable v-model="showIcon" :style="{ height: '20%' }"></nut-popup>
 
-        <nut-cell
-        isLink
-        title="图标位置"
-        :showIcon="true"
-        @click.native="showIconPosition = true">
-        </nut-cell>
-        <nut-popup
-        position="bottom"
-        closeable 
-        close-icon-position="top-left"
-        v-model="showIconPosition"
-        :style="{ height: '20%' }"
-        ></nut-popup>
+      <nut-cell isLink title="图标位置" :showIcon="true" @click.native="showIconPosition = true"> </nut-cell>
+      <nut-popup position="bottom" closeable close-icon-position="top-left" v-model="showIconPosition" :style="{ height: '20%' }"></nut-popup>
 
+      <nut-popup position="bottom" closeable close-icon="tick" v-model="showCloseIcon" :style="{ height: '20%' }"></nut-popup>
 
-        <nut-cell
-        isLink
-        title="自定义图标"
-        :showIcon="true"
-        @click.native="showCloseIcon = true">
-        </nut-cell>
-        <nut-popup
-        position="bottom"
-        closeable 
-        close-icon="tick"
-        v-model="showCloseIcon"
-        :style="{ height: '20%' }"
-        ></nut-popup>
+      <nut-cell isLink title="自定义图标" :showIcon="true" @click.native="showCloseIcon = true"> </nut-cell>
     </div>
 
-    <h2 class="title">圆角弹框</h2>
+    <h4>圆角弹框</h4>
     <div>
-        <nut-cell
-        isLink
-        title="圆角弹框"
-        :showIcon="true"
-        @click.native="showRound = true"
-        >
-        </nut-cell>
-        <nut-popup
-        round
-        v-model="showRound"
-        position="bottom"
-        :style="{ height: '20%' }"
-        ></nut-popup>
+      <nut-popup round v-model="showRound" position="bottom" :style="{ height: '20%' }"></nut-popup>
+      <nut-cell isLink title="圆角弹框" :showIcon="true" @click.native="showRound = true"> </nut-cell>
     </div>
-    <h2 class="title">指定挂载节点</h2>
+    <h4>指定挂载节点</h4>
     <div>
-        <nut-cell
-        isLink
-        title="指定挂载节点"
-        :showIcon="true"
-        @click.native="getContainer = true"
-        >
-        </nut-cell>
+      <nut-cell isLink title="指定挂载节点" :showIcon="true" @click.native="getContainer = true"> </nut-cell>
     </div>
-    <nut-popup :style="{ padding: '30px 50px' }"  get-container="body"  v-model="getContainer" >body</nut-popup>
+    <nut-popup :style="{ padding: '30px 50px' }" get-container="body" v-model="getContainer">body</nut-popup>
   </div>
 </template>
 <script>
@@ -149,29 +57,14 @@ export default {
       showRound: false,
       showIconPosition: false,
       showCloseIcon: false,
-      getContainer:false
+      getContainer: false,
     };
   },
-  methods: {     
+  methods: {
     show() {
       this.isShow = true;
-    }
-  }
+    },
+  },
 };
 </script>
-<style lang="scss" scoped>
-.title {
-  text-align: left;
-  margin: 0;
-  padding: 32px 16px 16px;
-  color: rgba(69, 90, 100, 0.6);
-  font-weight: normal;
-  font-size: 14px;
-  line-height: 16px;
-}
-.demo {
-  padding-left: 0;
-  padding-right: 0;
-  overflow: hidden;
-}
-</style>
+<style lang="scss" scoped></style>

+ 5 - 5
src/packages/popup/overlay/overlay.vue

@@ -33,21 +33,21 @@ const overlayProps = {
   },
   overlayClass: {
     type: String,
-    default: "",
+    default: '',
   },
   overlayStyle: {
     type: Object,
-    default: ()=>{},
+    default: () => {},
   },
   zIndex: {
-    type: Number
+    type: Number,
   },
 };
 export { overlayProps };
 export default {
-  name: "nut-popup-overlay",
+  name: 'nut-popup-overlay',
   props: overlayProps,
-   
+
   methods: {
     touchmove(e) {
       if (this.lockScroll) {

+ 132 - 120
src/packages/popup/popup.scss

@@ -1,167 +1,179 @@
 $popup-close-icon-margin: 16px;
+
 .popup-fade-enter-active {
-  animation: nut-fade-in;
+	animation: nut-fade-in;
 }
+
 .popup-fade-leave-active {
-  animation: nut-fade-out;
+	animation: nut-fade-out;
 }
 
 .popup-slide {
-  &-center-enter-active {
-    animation: nut-fade-in;
-  }
-  &-center-leave-active {
-    animation: nut-fade-out;
-  }
-
-  &-top-enter,
-  &-top-leave-active {
-    transform: translate(0, -100%);
-  }
-  &-right-enter,
-  &-right-leave-active {
-    transform: translate(100%, 0);
-  }
-
-  &-bottom-enter,
-  &-bottom-leave-active {
-    transform: translate(0, 100%);
-  }
-
-  &-left-enter,
-  &-left-leave-active {
-    transform: translate(-100%, 0);
-  }
+	&-center-enter-active {
+		animation: nut-fade-in;
+	}
+
+	&-center-leave-active {
+		animation: nut-fade-out;
+	}
+
+	&-top-enter,
+	&-top-leave-active {
+		transform: translate(0, -100%);
+	}
+
+	&-right-enter,
+	&-right-leave-active {
+		transform: translate(100%, 0);
+	}
+
+	&-bottom-enter,
+	&-bottom-leave-active {
+		transform: translate(0, 100%);
+	}
+
+	&-left-enter,
+	&-left-leave-active {
+		transform: translate(-100%, 0);
+	}
 }
 
 .popup-center {
-  top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
 }
 
 .popup-bottom {
-  bottom: 0;
-  left: 0;
-  width: 100%;
-  &.round {
-    border-radius: 25px 25px 0 0;
-  }
+	bottom: 0;
+	left: 0;
+	width: 100%;
+
+	&.round {
+		border-radius: 20px 20px 0 0;
+	}
 }
+
 .popup-right {
-  top: 0;
-  right: 0;
-  &.round {
-    border-radius: 25px 0 0 25px;
-  }
+	top: 0;
+	right: 0;
+
+	&.round {
+		border-radius: 20px 0 0 20px;
+	}
 }
 
 .popup-left {
-  top: 0;
-  left: 0;
-  &.round {
-    border-radius: 0 25px 25px 0;
-  }
+	top: 0;
+	left: 0;
+
+	&.round {
+		border-radius: 0 20px 20px 0;
+	}
 }
+
 .popup-top {
-  top: 0;
-  left: 0;
-  width: 100%;
-  &.round {
-    border-radius: 0 0 25px 25px;
-  }
+	top: 0;
+	left: 0;
+	width: 100%;
+
+	&.round {
+		border-radius: 0 0 20px 20px;
+	}
 }
+
 .popup-box {
-  position: fixed;
-  max-height: 100%;
-  overflow-y: auto;
-  background-color: #fff;
-  transition: transform 0.3s;
-  -webkit-overflow-scrolling: touch; 
+	position: fixed;
+	max-height: 100%;
+	overflow-y: auto;
+	background-color: #fff;
+	transition: transform 0.3s;
+	-webkit-overflow-scrolling: touch;
 }
+
 @keyframes nut-fade-in {
-  from {
-    opacity: 0;
-  }
+	from {
+		opacity: 0;
+	}
 
-  to {
-    opacity: 1;
-  }
+	to {
+		opacity: 1;
+	}
 }
 
 @keyframes nut-fade-out {
-  from {
-    opacity: 1;
-  }
+	from {
+		opacity: 1;
+	}
 
-  to {
-    opacity: 0;
-  }
+	to {
+		opacity: 0;
+	}
 }
 
 .nut-overflow-hidden {
-  overflow: hidden !important;
+	overflow: hidden !important;
 }
 
 .nutui-popup {
-  &__close-icon {
-    position: absolute;
-    z-index: 1;
-    color: #969799;
-    font-size: 18px;
-    cursor: pointer;
-
-    &:active {
-      opacity: 0.7;
-    }
-
-    &--top-left {
-      top: $popup-close-icon-margin;
-      left: $popup-close-icon-margin;
-    }
-
-    &--top-right {
-      top: $popup-close-icon-margin;
-      right: $popup-close-icon-margin;
-    }
-
-    &--bottom-left {
-      bottom: $popup-close-icon-margin;
-      left: $popup-close-icon-margin;
-    }
-
-    &--bottom-right {
-      right: $popup-close-icon-margin;
-      bottom: $popup-close-icon-margin;
-    }
-  }
+	&__close-icon {
+		position: absolute;
+		z-index: 1;
+		color: #969799;
+		font-size: 18px;
+		cursor: pointer;
+
+		&:active {
+			opacity: 0.7;
+		}
+
+		&--top-left {
+			top: $popup-close-icon-margin;
+			left: $popup-close-icon-margin;
+		}
+
+		&--top-right {
+			top: $popup-close-icon-margin;
+			right: $popup-close-icon-margin;
+		}
+
+		&--bottom-left {
+			bottom: $popup-close-icon-margin;
+			left: $popup-close-icon-margin;
+		}
+
+		&--bottom-right {
+			right: $popup-close-icon-margin;
+			bottom: $popup-close-icon-margin;
+		}
+	}
 }
 
 .popup-bg {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  background-color: rgba(0, 0, 0, 0.7); 
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background-color: rgba(0, 0, 0, 0.7);
 }
 
 @keyframes nut-fade-in {
-  from {
-    opacity: 0;
-  }
+	from {
+		opacity: 0;
+	}
 
-  to {
-    opacity: 1;
-  }
+	to {
+		opacity: 1;
+	}
 }
 
 @keyframes nut-fade-out {
-  from {
-    opacity: 1;
-  }
+	from {
+		opacity: 1;
+	}
 
-  to {
-    opacity: 0;
-  }
+	to {
+		opacity: 0;
+	}
 }

+ 41 - 19
src/packages/popup/popup.vue

@@ -34,48 +34,48 @@ const overflowScrollReg = /scroll|auto/i;
 const popupProps = {
   position: {
     type: String,
-    default: 'center'
+    default: 'center',
   },
 
   transition: String,
 
   closeable: {
     type: Boolean,
-    default: false
+    default: false,
   },
   closeIconPosition: {
     type: String,
-    default: 'top-right'
+    default: 'top-right',
   },
   closeIcon: {
     type: String,
-    default: 'cross'
+    default: 'cross',
   },
 
   closeOnClickOverlay: {
     type: Boolean,
-    default: true
+    default: true,
   },
 
   destroyOnClose: {
     type: Boolean,
-    default: false
+    default: false,
   },
   getContainer: String,
   round: {
     type: Boolean,
-    default: false
-  }
+    default: false,
+  },
 };
 export default {
   name: 'nut-popup',
   mixins: [touchMixins],
   components: {
-    icon: Icon
+    icon: Icon,
   },
   props: {
     ...overlayProps,
-    ...popupProps
+    ...popupProps,
   },
   created() {
     this.transition ? (this.transitionName = this.transition) : (this.transitionName = `popup-slide-${this.position}`);
@@ -86,7 +86,21 @@ export default {
     }
   },
   beforeDestroy() {
-    this.close();
+    if (this.value) {
+      this.close();
+    }
+  },
+  activated() {
+    if (this.keepAlive) {
+      this.$emit('input', true);
+      this.keepAlive = false;
+    }
+  },
+  deactivated() {
+    if (this.value) {
+      this.close();
+      this.keepAlive = true;
+    }
   },
   watch: {
     value(val) {
@@ -97,19 +111,19 @@ export default {
       val === 'center' ? (this.transitionName = 'popup-fade') : (this.transitionName = `popup-slide-${this.position}`);
     },
     getContainer: 'portal',
-    overlay: 'renderOverlay'
+    overlay: 'renderOverlay',
   },
   data() {
     return {
       showSlot: true,
       transitionName: 'popup-fade-center',
-      overlayInstant: null
+      overlayInstant: null,
     };
   },
   computed: {
     transitionDuration() {
       return this.duration ? this.duration + 's' : 'initial';
-    }
+    },
   },
 
   methods: {
@@ -117,7 +131,9 @@ export default {
       if (this.opened) {
         return;
       }
-
+      if(this.closeOnClickOverlay){
+        this.showSlot = true;
+      }
       this.opened = true;
       this.$emit('open');
 
@@ -128,7 +144,7 @@ export default {
         overlayClass,
         overlayStyle,
         lockScroll,
-        closeOnClickOverlay
+        closeOnClickOverlay,
       };
 
       this.renderOverlay(config);
@@ -190,7 +206,13 @@ export default {
         if (!overlayManager.lockCount) {
           document.body.classList.remove('nut-overflow-hidden');
         }
+      } 
+      if(this.closeOnClickOverlay){
+        setTimeout(()=>{
+          this.showSlot = false;
+        },this.duration*1000)        
       }
+      
 
       overlayManager.closeOverlay(this);
       this.$emit('input', false);
@@ -213,8 +235,8 @@ export default {
       if (container && container !== el.parentNode) {
         container.appendChild(el);
       }
-    }
-  }
+    },
+  },
 };
-export  {popupProps}
+export { popupProps };
 </script>