# 页面多分辨率适配
# 适配方案
前端多分辨率适配的方案有多种,主要包括以下内容:
- 使用rem响应式布局,代码需要重构
- 使用scale属性,维护已有页面较为容易,页面相对尺寸不变;缺点是页面缩放时字体会出现一定的模糊。
- 使用MutationObserver监听Dom
# 直接使用scale属性
通过计算当前页面或者当前设备物理分辨率,与设计图分辨率的差别,分别计算x、y方向的缩放因子。通过监听浏览器onresize事件,动态调整显示页面的缩放比例,以实现自适应的效果。
mounted () {
// 处理屏幕宽高比
this.handleScreenAuto()
window.onresize = () => {
this.handleScreenAuto()
}
},
beforeDestroy () {
window.onresize = null
},
methods: {
// 多分辨率显示器适配
handleScreenAuto () {
const designDraftWidth = 1920;//设计稿的宽度
const designDraftHeight = 1080;//设计稿的高度
const currentWidth = document.documentElement.clientWidth // 当前浏览器宽度
const currentHeight = document.documentElement.clientHeight // 当前浏览器高度
//宽高相同缩放比例,选择较小的
// const scale = currentWidth / currentHeight < designDraftWidth / designDraftHeight ?
// (currentWidth / designDraftWidth) :
// (currentHeight / designDraftHeight);
// //缩放比例
// (document.querySelector('#overview_contianer')).style.transform = `scale(${scale}) translate(-50%)`;
// 宽高不同缩放比例
const widthScale = currentWidth / designDraftWidth;
const heightScale = currentHeight / designDraftHeight;
// console.log(widthScale,heightScale)
(document.querySelector('#overview_contianer')).style.transform = `scale(${widthScale},${heightScale})`;
}
}
# 使用MutationObserver监听
<template>
<div :id="name" :ref="refName">
<slot v-if="ready"></slot>
</div>
</template>
<script>
export default {
name: 'BaseContainer',
props: {
// 区分组件
name: String,
options: Object,
refName: String,
},
data() {
return {
width: 0, // 设计图宽度
height: 0, // 设计图高度
originalWidth: 0, // 设备屏幕物理宽度
originalHeight: 0, // 设备屏幕物理高度
ready: false,
context: null,
dom: null,
observer: null,
};
},
mounted() {
this.ready = false;
this.context = this.$refs[this.refName];
this.initSize().then(() => {
this.updateSize();
this.updateScale();
window.addEventListener('resize', this.onResize);
this.initMutationObserver();
this.ready = true;
});
},
methods: {
// 初始化尺寸
async initSize() {
await this.$nextTick();
this.dom = this.$refs[this.refName];
if (this.options && this.options.width && this.options.height) {
this.width = this.options.width;
this.height = this.options.height;
} else {
this.width = this.dom.clientWidth;
this.height = this.dom.clientHeight;
}
if (!this.originalWidth || !this.originalHeight) {
this.originalWidth = window.screen.width;
this.originalHeight = window.screen.height;
}
},
// 更新尺寸
updateSize() {
if (this.width && this.height) {
this.dom.style.width = `${this.width}px`;
this.dom.style.height = `${this.height}px`;
} else {
this.dom.style.width = `${this.originalWidth}px`;
this.dom.style.height = `${this.originalHeight}px`;
}
},
// 更新宽高比
updateScale() {
const currentWidth = document.body.clientWidth;
const currentHeight = document.body.clientHeight;
const realWidth = this.width || this.originalWidth; // 默认用设计尺寸
const realHeight = this.height || this.originalHeight;
const widthScale = currentWidth / realWidth;
const heightScale = currentHeight / realHeight;
this.dom.style.transform = `scale(${widthScale},${heightScale})`;
},
// onresize 事件响应函数
onResize() {
this.initSize().then(() => {
this.updateScale();
});
},
// 初始化事件监听器
initMutationObserver() {
// 创建MutationObserver 在DOM发生变化时被调用
const MutationObserver = window.MutationObserver;
this.observer = new MutationObserver(this.onResize);
this.observer.observe(this.dom, {
attributes: true, // 监听所有节点属性值
attributeFilter: ['style'], // 指定被监听的属性列表
attributeOldValue: true, // 记录上一次被监听的节点属性变化
});
},
removeMutationObserver() {
if (this.observer) {
this.observer.disconnect(); // 阻止继续接收变化的通知
this.observer.takeRecords();
this.observer = null;
}
},
},
beforeDestroy() {
window.removeEventListener('resize', this.onResize);
this.removeMutationObserver();
},
};
</script>
<style scoped>
#base-container {
position: fixed;
top: 0;
left: 0;
overflow: hidden;
transform-origin: left top;
z-index: 999;
}
</style>
← 数据类型√