关于vue.js:Vue全屏组件

8次阅读

共计 3908 个字符,预计需要花费 10 分钟才能阅读完成。

全屏组件 FullScreenContainer 目录构造

index.vue

<template>
  <div id="sp-full-screen-container" :ref="ref">
    <div id="sp-full-screen-container-content">
      <template v-if="ready">
        <slot></slot>
      </template>
    </div>
  </div>
</template>
<script>
import autoResize from "./mixin/autoResize.js";

export default {
  name: "FullScreenContainer",
  mixins: [autoResize],
  props: {
    // 设计稿画布大小(单位:px)canvasWidth: {
      type: Number,
      default: 0,
    },
    canvasHeight: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      ref: "sp-full-screen-container",
      ready: false,
      scale: 1.0,
    };
  },
  methods: {afterAutoResizeMixinInit() {const { initConfig, setContainerScale} = this;

      initConfig();

      setContainerScale();

      this.ready = true;
    },
    initConfig() {const { dom, canvasWidth, canvasHeight} = this;
      // debugger;
      if (canvasWidth > 0 && canvasHeight > 0) {dom.style.cssText = `width: ${canvasWidth}px; height: ${canvasHeight}px;`;
      }
    },
    setContainerScale() {const { width, height, dom} = this;
      const {innerWidth, innerHeight} = window;

      let top = 0;
      let left = 0;
      let scale = 0;
      // 设置缩放率并居中
      if (innerWidth / innerHeight > width / height) {
        // 高低居中
        scale = innerHeight / height;
        left = (innerWidth - scale * 1920) / 2;
      } else {
        // 左右居中
        scale = innerWidth / width;
        // top = 0;
      }

      // 防止死循环
      if (this.scale == scale) {dom.style.left = `${left}px`;
        dom.style.top = `${top}px`;
        dom.style.transform = `scale(${scale})`;
        return;
      }
      this.scale = scale;

      if (width == 0 || height == 0) {dom.style.left = `${left}px`;
        dom.style.top = `${top}px`;
        dom.style.transform = `scale(${scale})`;
      } else {
        // 升高 DOM 操作次数
        dom.style.cssText = `width: ${width}px; height: ${height}px; left: ${left}px; top: ${top}px; transform: scale(${scale});`;
      }
    },
    onResize() {const { setContainerScale} = this;

      setContainerScale();},
  },
};
</script>

<style lang="less">
#sp-full-screen-container {
  position: fixed;
  top: 0px;
  left: 0px;
  overflow: visible;
  -webkit-transform-origin: left top;
  transform-origin: left top;
  z-index: 999;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

autoResize.js

import {debounce, observerDomResize} from "../util/index";

export default {data() {
    return {
      dom: "",

      width: 0,
      height: 0,

      debounceInitWHFun: "",

      domObserver: "",
    };
  },
  methods: {async autoResizeMixinInit() {
      const {
        initWH,
        getDebounceInitWHFun,
        bindDomResizeCallback,
        afterAutoResizeMixinInit,
      } = this;

      await initWH(false);

      getDebounceInitWHFun();

      bindDomResizeCallback();

      if (typeof afterAutoResizeMixinInit === "function")
        afterAutoResizeMixinInit();},
    initWH(resize = true) {const { $nextTick, $refs, ref, onResize} = this;

      return new Promise((resolve) => {$nextTick(() => {const dom = (this.dom = $refs[ref]);

          this.width = dom.clientWidth;
          this.height = dom.clientHeight;

          if (typeof onResize === "function" && resize) onResize();

          resolve();});
      });
    },
    getDebounceInitWHFun() {const { initWH} = this;

      this.debounceInitWHFun = debounce(100, initWH);
    },
    bindDomResizeCallback() {const { dom, debounceInitWHFun} = this;

      this.domObserver = observerDomResize(dom, debounceInitWHFun);

      window.addEventListener("resize", debounceInitWHFun);
    },
    unbindDomResizeCallback() {let { domObserver, debounceInitWHFun} = this;

      domObserver.disconnect();
      domObserver.takeRecords();
      domObserver = null; // NOSONAR

      window.removeEventListener("resize", debounceInitWHFun);
    },
  },
  mounted() {const { autoResizeMixinInit} = this;

    autoResizeMixinInit();},
  onBeforeUnMount() {const { unbindDomResizeCallback} = this;

    unbindDomResizeCallback();},
};

util/index.js

export function randomExtend(minNum, maxNum) {if (arguments.length === 1) {return parseInt(Math.random() * minNum + 1, 10);
  } else {return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
  }
}

export function debounce(delay, callback) {
  let lastTime;

  return function () {clearTimeout(lastTime);

    const [that, args] = [this, arguments];

    lastTime = setTimeout(() => {callback.apply(that, args);
    }, delay);
  };
}

export function observerDomResize(dom, callback) {
  const MutationObserver =
    window.MutationObserver ||
    window.WebKitMutationObserver ||
    window.MozMutationObserver;

  const observer = new MutationObserver(callback);

  observer.observe(dom, {
    attributes: true,
    attributeFilter: ["style"],
    attributeOldValue: true,
  });

  return observer;
}

export function getPointDistance(pointOne, pointTwo) {const minusX = Math.abs(pointOne[0] - pointTwo[0]);

  const minusY = Math.abs(pointOne[1] - pointTwo[1]);

  return Math.sqrt(minusX * minusX + minusY * minusY);
}
正文完
 0