|
|
@@ -0,0 +1,175 @@
|
|
|
+<template>
|
|
|
+ <div id="adaptive-container" :ref="refName">
|
|
|
+ <template v-if="ready">
|
|
|
+ <slot></slot>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import { ref, onMounted, onUnmounted, nextTick, defineComponent } from 'vue';
|
|
|
+ import { debounce, setRem } from '/@/utils/index';
|
|
|
+ import { useAppStore } from '/@/store/modules/app';
|
|
|
+ import { getActions } from '/@/qiankun/state';
|
|
|
+
|
|
|
+ export default defineComponent({
|
|
|
+ name: 'AdaptiveContainer',
|
|
|
+ props: {
|
|
|
+ options: Object,
|
|
|
+ },
|
|
|
+ setup(ctx) {
|
|
|
+ const appStore = useAppStore();
|
|
|
+
|
|
|
+ const refName = 'AdaptiveContainer'; //AdaptiveContainer
|
|
|
+ // 屏幕宽度
|
|
|
+ const width = ref(0);
|
|
|
+ // 屏幕高度
|
|
|
+ const height = ref(0);
|
|
|
+ // 原始屏幕宽度
|
|
|
+ const originalWidth = ref(0);
|
|
|
+ // 原始屏幕高度
|
|
|
+ const originalHeight = ref(0);
|
|
|
+ // 控制显示
|
|
|
+ const ready = ref(false);
|
|
|
+ /*
|
|
|
+ * dom:well-container的dom
|
|
|
+ * observer: window.MutationObserver(Bom实例)监听dom改变
|
|
|
+ */
|
|
|
+ let dom, observer;
|
|
|
+ const actions = getActions();
|
|
|
+
|
|
|
+ //设置初始值
|
|
|
+ const initSize = () => {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ nextTick(() => {
|
|
|
+ dom = document.getElementById('adaptive-container');
|
|
|
+ // 获取大屏的传入尺寸
|
|
|
+ if (ctx.options && ctx.options.width && ctx.options.height) {
|
|
|
+ //传入宽高
|
|
|
+ width.value = ctx.options.width;
|
|
|
+ height.value = ctx.options.height;
|
|
|
+ } else {
|
|
|
+ //可见宽高
|
|
|
+ width.value = dom.clientWidth;
|
|
|
+ height.value = dom.clientHeight;
|
|
|
+ }
|
|
|
+ // 获取画布尺寸
|
|
|
+ if (!originalWidth.value || !originalHeight.value) {
|
|
|
+ //屏幕分辨率宽高
|
|
|
+ originalWidth.value = window.screen.width;
|
|
|
+ originalHeight.value = window.screen.height;
|
|
|
+ }
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const updateSize = () => {
|
|
|
+ if (width.value && height.value) {
|
|
|
+ dom.style.width = `${width.value}px`;
|
|
|
+ dom.style.height = `${height.value}px`;
|
|
|
+ } else {
|
|
|
+ dom.style.width = `${originalWidth.value}px`;
|
|
|
+ dom.style.height = `${originalHeight.value}px`;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const updateScale = () => {
|
|
|
+ // debugger
|
|
|
+ // 获取真实的视口尺寸
|
|
|
+ const currentWidth = document.body.clientWidth;
|
|
|
+ const currentHeight = document.body.clientHeight;
|
|
|
+ // 获取大屏最终的宽高
|
|
|
+ const realWidth = width.value || originalWidth.value;
|
|
|
+ const realHeight = height.value || originalHeight.value;
|
|
|
+ // console.log(currentWidth, currentHeight)
|
|
|
+ // 缩放比例 = 分辨率宽高 / 传入宽高(可视宽高)
|
|
|
+ const widthScale = currentWidth / realWidth;
|
|
|
+ const heightScale = currentHeight / realHeight;
|
|
|
+ appStore.setWidthScale(widthScale);
|
|
|
+ appStore.setHeightScale(heightScale);
|
|
|
+ actions.setGlobalState({ widthScale, heightScale });
|
|
|
+
|
|
|
+ //如果dom存在,就按照比例缩放
|
|
|
+ dom && (dom.style.transform = `scale(${widthScale}, ${heightScale})`);
|
|
|
+ };
|
|
|
+ const cssSize = () => {
|
|
|
+ const currentWidth = document.body.clientWidth;
|
|
|
+ const realWidth = width.value || originalWidth.value;
|
|
|
+ const whdef = 100 / currentWidth; // 表示1920的设计图,使用100PX的默认值
|
|
|
+ const wW = currentWidth / realWidth; // 当前窗口的宽度
|
|
|
+ const rem = wW * whdef; // 以默认比例值乘以当前窗口宽度,得到该宽度下的相应FONT-SIZE值
|
|
|
+ // document.documentElement.style.fontSize = rem + 'px';
|
|
|
+ document.documentElement.style.fontSize = rem + 'px';
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ const whdef = 100 / currentWidth; // 表示1920的设计图,使用100PX的默认值
|
|
|
+ const wW = window.innerWidth; // 当前窗口的宽度
|
|
|
+ const rem = wW * whdef; // 以默认比例值乘以当前窗口宽度,得到该宽度下的相应FONT-SIZE值
|
|
|
+ document.documentElement.style.fontSize = rem + 'px';
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ //重置缩放比例
|
|
|
+ const onResize = async () => {
|
|
|
+ // debugger;
|
|
|
+ await initSize();
|
|
|
+ updateScale();
|
|
|
+ setRem();
|
|
|
+ cssSize();
|
|
|
+ };
|
|
|
+
|
|
|
+ const initMutationObserver = () => {
|
|
|
+ //监听元素属性变化
|
|
|
+ const MutationObserver = window.MutationObserver;
|
|
|
+ //如果变化,就用onResize重置屏幕所缩放比例
|
|
|
+ observer = new MutationObserver(onResize);
|
|
|
+ observer.observe(dom, {
|
|
|
+ attributes: true,
|
|
|
+ // attributeFilter: ['style'],
|
|
|
+ attributeOldValue: true,
|
|
|
+ });
|
|
|
+ };
|
|
|
+ //移除监听属性
|
|
|
+ const removeMutationObserver = () => {
|
|
|
+ if (observer) {
|
|
|
+ observer.disconnect();
|
|
|
+ observer.takeRecords();
|
|
|
+ observer = null;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ //
|
|
|
+ onMounted(async () => {
|
|
|
+ ready.value = false;
|
|
|
+ await initSize();
|
|
|
+ updateSize();
|
|
|
+ updateScale();
|
|
|
+ setRem();
|
|
|
+ cssSize();
|
|
|
+ window.addEventListener('resize', debounce(100, onResize));
|
|
|
+ // initMutationObserver();
|
|
|
+ ready.value = true;
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', onResize);
|
|
|
+ // removeMutationObserver();
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ refName,
|
|
|
+ ready,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+ #adaptive-container {
|
|
|
+ position: relative;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ transform-origin: left top;
|
|
|
+ z-index: 0;
|
|
|
+ }
|
|
|
+</style>
|