Ver código fonte

矩阵监视弹框修改

limiao 4 anos atrás
pai
commit
0117af0b06
3 arquivos alterados com 2449 adições e 1779 exclusões
  1. 1880 1779
      components/monitor/MatrixMonitor.vue
  2. 95 0
      s-popup/README.md
  3. 474 0
      s-popup/index.vue

Diferenças do arquivo suprimidas por serem muito extensas
+ 1880 - 1779
components/monitor/MatrixMonitor.vue


+ 95 - 0
s-popup/README.md

@@ -0,0 +1,95 @@
+# 提示
+后续将不在插件市场更新,组件包和示例请访问github中[s-ui地址](https://github.com/sldt/s-ui)下载
+
+# s-popup
+
+## 参数说明
+
+``` js
+{
+  // class
+  customClass: {
+    type: String,
+    default: ''
+  },
+  // v-model双向绑定
+  value: Boolean,
+  // 弹框显示位置 center | left | right | top | bottom
+  position: {
+    type: String,
+    default: 'center'
+  },
+  // 是否使用过渡效果
+  effect: {
+    type: Boolean,
+    default: true
+  },
+  // 过渡时间
+  effectDuration: {
+    type: Number,
+    default: 300
+  },
+  // 是否显示遮罩
+  mask: {
+    type: Boolean,
+    default: true
+  },
+  // 遮罩透明度
+  maskOpacity: {
+    type: Number,
+    default: 0.7
+  },
+  // 点击遮罩是否关闭弹框
+  maskClose: {
+    type: Boolean,
+    default: true
+  },
+  // 自动关闭时间
+  duration: {
+    type: Number,
+    default: 0
+  },
+  // 是否阻止弹层touchmove滚动,手机上滚动穿透
+  preventTouchmove: {
+    type: Boolean,
+    default: false
+  },
+  // 显示时拦截钩子返回promise拦截
+  beforeShow: Function,
+  // 隐藏时拦截钩子返回promise拦截
+  beforeHide: Function
+}
+```
+
+## 使用方式
+
+#### template
+``` html
+<s-popup custom-class="demo-popup" position="bottom" v-model="visible">
+  <!-- 内容 -->
+</s-popup>
+```
+
+#### script
+``` js
+import sPopup from '@/s-ui/s-popup';
+export default {
+  components: {
+    sPopup
+  },
+  data (){
+    return {
+      visible: true
+    }
+  }
+}
+```
+
+#### style
+``` css
+.demo-popup{
+  .s-popup-wrapper{
+
+  }
+}
+```

+ 474 - 0
s-popup/index.vue

@@ -0,0 +1,474 @@
+<template>
+  <view
+    :class="['s-popup',positionClass,visibleClass,effectClass,customClass]"
+    :style="styleZindex+styleDuration"
+  >
+    <template v-if="mask">
+      <view
+        class="s-popup-mask"
+        @touchmove.stop.prevent="e=>e.preventDefault()"
+        @click="maskClose && hide()"
+        :style="'background-color: rgba(0, 0, 0, '+maskOpacity+');'"
+      ></view>
+    </template>
+    <view
+      v-if="preventTouchmove"
+      class="s-popup-wrapper"
+      @touchmove.stop.prevent="e=>e.preventDefault()"
+    >
+      <slot></slot>
+    </view>
+    <view v-else class="s-popup-wrapper">
+      <slot></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+
+// 记录弹框的zIndex
+const ZindexMap = new Map();
+const getMaxZindex = () => {
+  return Math.max(200, ...ZindexMap.values()) + 1;
+};
+
+export default {
+  name: 's-popup',
+  props: {
+    // class
+    customClass: {
+      type: String,
+      default: ''
+    },
+    // v-model双向绑定
+    value: Boolean,
+    // 弹框显示位置 center | left | right | top | bottom
+    position: {
+      type: String,
+      default: 'center'
+    },
+    // 是否使用过渡效果
+    effect: {
+      type: Boolean,
+      default: true
+    },
+    // 过渡时间
+    effectDuration: {
+      type: Number,
+      default: 300
+    },
+    // 是否显示遮罩
+    mask: {
+      type: Boolean,
+      default: true
+    },
+    // 遮罩透明度
+    maskOpacity: {
+      type: Number,
+      default: 0.7
+    },
+    // 点击遮罩是否关闭弹框
+    maskClose: {
+      type: Boolean,
+      default: true
+    },
+    // 自动关闭时间
+    duration: {
+      type: Number,
+      default: 0
+    },
+    // 是否阻止弹层touchmove滚动,手机上滚动穿透
+    preventTouchmove: {
+      type: Boolean,
+      default: false
+    },
+    // 显示时拦截钩子返回promise拦截
+    beforeShow: Function,
+    // 隐藏时拦截钩子返回promise拦截
+    beforeHide: Function
+  },
+  data () {
+    Object.assign(this, {
+      popupId: 's-popup-id-' + Math.random().toString(36).substr(2),
+      visibleId: 0,
+      visibleStatus: false,
+      effectTimeoutId: 0,
+      autoCloseTimeoutId: 0
+    });
+    return {
+      styleZindex: '',
+      visibleClass: '',
+      styleDuration: '',
+      effectClass: ''
+    };
+  },
+  computed: {
+    positionClass () {
+      return this.position ? 's-popup-position-' + this.position : '';
+    }
+  },
+  watch: {
+    value () {
+      this.updateVisible();
+    }
+  },
+  methods: {
+    async show () {
+      if (!this.visibleStatus) {
+        this.visibleId++;
+        let status = true;
+        const nowId = this.visibleId;
+        if (this.beforeShow) {
+          try {
+            await this.beforeShow.call(this.$parent);
+          } catch (error) {
+            status = false;
+          }
+        }
+        if (nowId === this.visibleId) {
+          if (status) {
+            const effectDuration = this.effect ? this.effectDuration : 0;
+            this.visibleStatus = true;
+            this.$emit('input', true);
+            ZindexMap.set(this.popupId, getMaxZindex());
+            this.styleZindex = `z-index:${ZindexMap.get(this.popupId)};`;
+            this.styleDuration = `animation-duration:${effectDuration}ms;`;
+            this.visibleClass = 's-popup-visible';
+            this.effectClass = 's-popup-effect-enter';
+            clearTimeout(this.effectTimeoutId);
+            this.effectTimeoutId = setTimeout(() => {
+              this.styleDuration = '';
+              this.effectClass = '';
+              if (this.visibleStatus) {
+                this.$emit('show');
+                // 自动关闭
+                const duration = parseInt(this.duration);
+                if (duration > 0) {
+                  clearTimeout(this.autoCloseTimeoutId);
+                  this.autoCloseTimeoutId = setTimeout(() => {
+                    this.visibleStatus && this.hide();
+                  }, duration);
+                }
+              }
+            }, effectDuration);
+          } else {
+            this.$emit('input', false);
+          }
+        }
+      }
+    },
+    async hide () {
+      if (this.visibleStatus) {
+        this.visibleId++;
+        let status = true;
+        const nowId = this.visibleId;
+        if (this.beforeHide) {
+          try {
+            await this.beforeHide.call(this.$parent);
+          } catch (error) {
+            status = false;
+          }
+        }
+        if (nowId === this.visibleId) {
+          if (status) {
+            const effectDuration = this.effect ? this.effectDuration : 0;
+            this.visibleStatus = false;
+            this.$emit('input', false);
+            this.styleDuration = 'animation-duration:' + effectDuration + 'ms;';
+            this.effectClass = 's-popup-effect-leave';
+            clearTimeout(this.autoCloseTimeoutId);
+            clearTimeout(this.effectTimeoutId);
+            this.effectTimeoutId = setTimeout(() => {
+              this.visibleClass = '';
+              this.effectClass = '';
+              this.styleZindex = '';
+              this.styleDuration = '';
+              ZindexMap.delete(this.popupId);
+              if (!this.visibleStatus) {
+                this.$emit('hide');
+              }
+            }, effectDuration);
+          } else {
+            this.$emit('input', true);
+          }
+        }
+      }
+    },
+    updateVisible () {
+      this.$nextTick(() => {
+        if (this.visibleStatus !== this.value) {
+          this[this.value ? 'show' : 'hide']();
+        }
+      });
+    }
+  },
+  mounted () {
+    this.updateVisible();
+  },
+  beforeDestroy () {
+    ZindexMap.delete(this.popupId);
+    clearTimeout(this.effectTimeoutId);
+    clearTimeout(this.autoCloseTimeoutId);
+  }
+};
+</script>
+
+<style lang="scss">
+// fade效果
+@keyframes s-popup-fade-enter {
+  0% {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+@keyframes s-popup-fade-leave {
+  0% {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+  }
+}
+
+// 显示和隐藏效果
+@keyframes s-popup-center-enter {
+  0% {
+    opacity: 0;
+    transform: scale(0.7);
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+@keyframes s-popup-center-leave {
+  0% {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    transform: scale(0.9);
+  }
+}
+
+@keyframes s-popup-top-enter {
+  0% {
+    transform: translate3d(0, -100%, 0);
+  }
+
+  to {
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+@keyframes s-popup-top-leave {
+  to {
+    transform: translate3d(0, -100%, 0);
+  }
+}
+
+@keyframes s-popup-left-enter {
+  0% {
+    transform: translate3d(-100%, 0, 0);
+  }
+
+  to {
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+@keyframes s-popup-left-leave {
+  to {
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+
+@keyframes s-popup-right-enter {
+  0% {
+    transform: translate3d(100%, 0, 0);
+  }
+
+  to {
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+@keyframes s-popup-right-leave {
+  to {
+    transform: translate3d(100%, 0, 0);
+  }
+}
+
+@keyframes s-popup-bottom-enter {
+  0% {
+    transform: translate3d(0, 100%, 0);
+  }
+
+  to {
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+@keyframes s-popup-bottom-leave {
+  to {
+    transform: translate3d(0, 100%, 0);
+  }
+}
+.s-popup {
+  display: none;
+  position: fixed;
+  left: 0;
+  right: 0;
+  top: var(--window-top);
+  bottom: var(--window-bottom);
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+  pointer-events: none;
+  &-visible {
+    display: flex;
+  }
+  &-mask {
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 1;
+    pointer-events: auto;
+  }
+
+  &-wrapper {
+    position: absolute;
+    max-width: 100%;
+    max-height: 100%;
+    z-index: 2;
+    pointer-events: auto;
+    background-color: white;
+    overflow: auto;
+  }
+  // 弹框效果
+  animation-fill-mode: both;
+  &-mask,
+  &-wrapper {
+    animation-fill-mode: both;
+    animation-duration: inherit;
+  }
+  &-effect-enter {
+    .s-popup-mask,
+    .s-popup-wrapper {
+      animation-name: s-popup-fade-enter;
+    }
+  }
+  &-effect-leave {
+    .s-popup-mask,
+    .s-popup-wrapper {
+      animation-name: s-popup-fade-leave;
+    }
+  }
+}
+
+//center
+.s-popup-position-center {
+  justify-content: center;
+  align-items: center;
+  .s-popup-wrapper {
+    position: relative;
+  }
+
+  &.s-popup-effect-enter {
+    .s-popup-wrapper {
+      animation-name: s-popup-center-enter;
+    }
+  }
+
+  &.s-popup-effect-leave {
+    .s-popup-wrapper {
+      animation-name: s-popup-center-leave;
+    }
+  }
+}
+//top
+.s-popup-position-top {
+  .s-popup-wrapper {
+    left: 0;
+    right: 0;
+    top: 0;
+  }
+  &.s-popup-effect-enter {
+    .s-popup-wrapper {
+      animation-name: s-popup-top-enter;
+    }
+  }
+
+  &.s-popup-effect-leave {
+    .s-popup-wrapper {
+      animation-name: s-popup-top-leave;
+    }
+  }
+}
+//bottom
+.s-popup-position-bottom {
+  .s-popup-wrapper {
+    left: 0;
+    right: 0;
+    bottom: 0;
+  }
+  &.s-popup-effect-enter {
+    .s-popup-wrapper {
+      animation-name: s-popup-bottom-enter;
+    }
+  }
+
+  &.s-popup-effect-leave {
+    .s-popup-wrapper {
+      animation-name: s-popup-bottom-leave;
+    }
+  }
+}
+//从左侧滑入
+.s-popup-position-left {
+  .s-popup-wrapper {
+    left: 0;
+    top: 0;
+    bottom: 0;
+  }
+  &.s-popup-effect-enter {
+    .s-popup-wrapper {
+      animation-name: s-popup-left-enter;
+    }
+  }
+
+  &.s-popup-effect-leave {
+    .s-popup-wrapper {
+      animation-name: s-popup-left-leave;
+    }
+  }
+}
+//从右侧滑入
+.s-popup-position-right {
+  .s-popup-wrapper {
+    right: 0;
+    top: 0;
+    bottom: 0;
+  }
+  &.s-popup-effect-enter {
+    .s-popup-wrapper {
+      animation-name: s-popup-right-enter;
+    }
+  }
+
+  &.s-popup-effect-leave {
+    .s-popup-wrapper {
+      animation-name: s-popup-right-leave;
+    }
+  }
+}
+</style>