layout-app.vue 1.9 KB
<template>
  <div ref="layout" class="layout" @touchstart="webviewScrollStart" @touchmove="webviewScrollMove" @touchend="webviewScrollEnd">
    <slot name="header">
      <LayoutHeader
        v-if="!hideHeader"
        class="layout-header"
        :title="title"
        :opacity="opacity"
        :show-back="showBack"
        :back-action="backAction"
      ></LayoutHeader>
    </slot>

    <div class="layout-context" :class="{ fixscroll: this.fixscroll }">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "LayoutApp",
  props: {
    title: String,
    opacity: {
      type: Number,
      default: 1
    },
    fixscroll: {
      type: Boolean,
      default: false
    },
    showBack: {
      type: Boolean,
      default: true
    },
    hideHeader: {
      type: Boolean,
      default: false
    },
    backAction: {
      type: Function,
      default: null
    },
    isStop: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isTouchStart: false,
      touchStartY: 0,
      touchMoveY: 0
    };
  },
  methods: {
    webviewScrollStart(e) {
      this.isTouchStart = true;
      this.touchStartY = e.changedTouches[0].pageY;
    },
    webviewScrollMove(e) {
      if (this.isTouchStart && !this.isStop) {
        let scrollTop = this.$refs.layout.scrollTop;

        this.touchMoveY = e.changedTouches[0].pageY;
        if (scrollTop <= 0 && this.touchMoveY > this.touchStartY) {
          e.preventDefault();
        }
      }
    },
    webviewScrollEnd() {
      this.isTouchStart = false;
    }
  }
};
</script>

<style lang="scss">
.layout {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  font-size: 24px;
  display: flex;
  flex-direction: column;
  background-color: #fff;

  .layout-context {
    flex: 1;
    overflow: hidden;
    position: relative;
  }

  .fixscroll {
    overflow: scroll;
  }
}
</style>