| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <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 / 1920; // 表示1920的设计图,使用100PX的默认值
- const wW = currentWidth / realWidth; // 当前窗口的宽度
- const rem = wW * whdef; // 以默认比例值乘以当前窗口宽度,得到该宽度下的相应FONT-SIZE值
- document.documentElement.style.fontSize = rem + 'px';
- window.addEventListener('resize', function () {
- const whdef = 100 / 1920; // 表示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>
|