vue-resize-plugin
v1.0.1
Published
用于页面自适应大小的一款插件
Readme
使用
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import { ScreenAdaptPlugin } from './plugins/screen-adapt';
const app = createApp(App);
app.use(ScreenAdaptPlugin, {
designWidth: 1920,
designHeight: 1080,
maxScale: 1.2,
minScale: 0.6
});
app.mount('#app');<!-- 大屏组件示例 -->
<template>
<div class="dashboard-container">
<div class="header" v-adapt-font:24>数据监控大屏</div>
<div class="grid-container">
<div class="card" v-adapt-font:16>
<h3>访问量统计</h3>
<ChartComponent :data="visitorData" />
</div>
<div class="card" v-adapt-font:16>
<h3>实时在线人数</h3>
<ChartComponent :data="onlineData" />
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, inject } from 'vue';
import ChartComponent from './ChartComponent.vue';
// 获取屏幕缩放比例
const screenScale = inject('screenScale');
// 响应式数据
const visitorData = ref([120, 190, 300, 240, 290, 350, 400]);
const onlineData = ref([50, 80, 120, 90, 150, 180, 200]);
// 计算样式
const cardStyle = computed(() => ({
width: `${500 * screenScale}px`,
height: `${300 * screenScale}px`
}));
</script>
<style scoped>
.dashboard-container {
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
}
.header {
text-align: center;
margin-bottom: 20px;
}
.grid-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
background-color: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
</style>// 动态字体适配
// utils/font-adapt.js
export const adaptFontSize = (size) => {
const scale = screenAdapt.getScale();
return `${size * scale}px`;
};
// 或使用CSS变量方案
export const setupFontVariables = () => {
const scale = screenAdapt.getScale();
document.documentElement.style.setProperty('--base-font-size', `${16 * scale}px`);
};
<!--图表适配-->
<!-- ChartComponent.vue -->
<template>
<div class="chart-container" :style="chartStyle">
<canvas ref="chartCanvas"></canvas>
</div>
</template>
<script setup>
import { ref, onMounted, watch, inject } from 'vue';
import Chart from 'chart.js/auto';
const props = defineProps({
data: {
type: Array,
required: true
}
});
const chartCanvas = ref(null);
const chartInstance = ref(null);
const screenScale = inject('screenScale');
const chartStyle = computed(() => ({
width: '100%',
height: `${200 * screenScale}px`
}));
const initChart = () => {
if (chartInstance.value) {
chartInstance.value.destroy();
}
const ctx = chartCanvas.value.getContext('2d');
chartInstance.value = new Chart(ctx, {
type: 'line',
data: {
labels: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
datasets: [{
label: '数据趋势',
data: props.data,
borderColor: '#36A2EB',
backgroundColor: 'rgba(54, 162, 235, 0.1)',
tension: 0.3,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
font: {
size: 12 * screenScale
}
}
}
},
scales: {
y: {
ticks: {
font: {
size: 10 * screenScale
}
}
},
x: {
ticks: {
font: {
size: 10 * screenScale
}
}
}
}
}
});
};
onMounted(() => {
initChart();
});
watch(() => [props.data, screenScale], () => {
if (chartCanvas.value) {
initChart();
}
});
</script>
// 使用动态导入优化首屏加载
const HeavyComponent = defineAsyncComponent(() => import('./HeavyComponent.vue'));
// 在大屏中按需渲染
<template>
<div v-if="showHeavyComponent">
<HeavyComponent />
</div>
</template>
/*混合使用vw/vh与rem*/
/* 基础样式配置 */
:root {
--base-font-size: 16px;
--design-width: 1920;
--design-height: 1080;
}
/* 计算vw基准值 */
html {
font-size: calc(100vw / var(--design-width) * 10);
}
/* 组件样式 */
.container {
width: 50rem; /* 相当于设计稿中的500px */
height: 30rem; /* 相当于设计稿中的300px */
font-size: 1.6rem; /* 相当于设计稿中的16px */
}
/* 特殊尺寸使用vh */
.title {
font-size: 2vh; /* 相对于视口高度的2% */
}
/* 媒体查询断点 */
/* 针对不同尺寸屏幕的调整 */
@media (max-width: 1600px) {
.card {
width: 40rem;
height: 25rem;
}
}
@media (max-width: 1366px) {
.card {
width: 35rem;
height: 22rem;
}
}
// 多分辨率测试
// 测试工具:模拟不同分辨率
const testResolutions = [
{ width: 1920, height: 1080 },
{ width: 1600, height: 900 },
{ width: 1366, height: 768 },
{ width: 1280, height: 720 }
];
const simulateResolution = (resolution) => {
document.documentElement.style.width = `${resolution.width}px`;
document.documentElement.style.height = `${resolution.height}px`;
window.dispatchEvent(new Event('resize'));
};
// 性能监控
// 使用Performance API监控渲染性能
const monitorPerformance = () => {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log('性能指标:', entry);
});
});
observer.observe({ entryTypes: ['frame', 'longtask'] });
};
