Appearance
BizScreenContainer 大屏适配容器
数据可视化大屏的等比缩放适配容器:内容按设计稿固定尺寸(默认 1920×1080)编排,transform: scale 适配任意分辨率容器——fit 等比缩放居中(比例不一致留边)、stretch 拉伸填满;ResizeObserver 实时响应容器 / 窗口尺寸变化,resize 外抛当前缩放比。与 BizChart(图表)、BizFullScreen(全屏投放)、BizWatermark(水印)、BizThemeSwitch 组成大屏基建。
基础等比适配
城市运行监测大屏
接入设备12,806台
今日告警37条
在线率99.2%
平均响应86ms
图表区(BizChart 可直接放入,随容器等比缩放)
1920×1080 设计稿内容在任意尺寸容器中等比缩放居中(拖动窗口观察)。
<script setup lang="ts">
/** 场景:基础等比适配——1920×1080 设计稿在任意容器中等比缩放居中 */
import { BizScreenContainer } from 'vue3-ep-biz-lib'
const stats = [
{ label: '接入设备', value: '12,806', unit: '台' },
{ label: '今日告警', value: '37', unit: '条' },
{ label: '在线率', value: '99.2', unit: '%' },
{ label: '平均响应', value: '86', unit: 'ms' },
]
</script>
<template>
<div style="height: 360px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer :width="1920" :height="1080">
<div
style="
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background:
radial-gradient(1200px 500px at 50% -10%, rgba(56, 189, 248, 0.18), transparent 60%),
linear-gradient(180deg, #0b1628, #0d1a30);
color: #e2e8f0;
"
>
<div
style="
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
padding: 28px 0 18px;
border-bottom: 1px solid rgba(56, 189, 248, 0.25);
"
>
<span style="font-size: 44px; font-weight: 700; letter-spacing: 10px">城市运行监测大屏</span>
</div>
<div style="flex: 1; display: flex; gap: 20px; padding: 20px 48px 32px">
<div
v-for="s in stats"
:key="s.label"
style="
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
padding: 22px 24px;
border: 1px solid rgba(56, 189, 248, 0.25);
border-radius: 10px;
background: rgba(56, 189, 248, 0.07);
"
>
<span style="font-size: 18px; opacity: 0.65">{{ s.label }}</span>
<span style="font-size: 40px; font-weight: 700; color: #7dd3fc">
{{ s.value }}<span style="font-size: 16px; margin-left: 4px">{{ s.unit }}</span>
</span>
</div>
</div>
<div
style="
margin: 0 48px 28px;
flex: none;
height: 200px;
border: 1px dashed rgba(56, 189, 248, 0.35);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
opacity: 0.75;
"
>
图表区(BizChart 可直接放入,随容器等比缩放)
</div>
</div>
</BizScreenContainer>
</div>
</template>
显示代码
综合数据大屏
园区经济运行总览 数据周期:2026-09
今日产值3,842万+12.4%
能耗强度0.42吨-3.1%
开工率91.6%+0.8%
安全运行326天持平
产业结构占比
智能制造 42%新能源 26%生物医药 18%其他 14%
月度产值走势(亿元)
部门产值 TOP5
11,286
智能制造事业部
21,043
新能源事业部
3872
生物医药园
4691
数字服务基地
5528
新材料中心
典型大屏编排:标题栏 + 指标带 + 环图 / 柱图 / 排行三栏(纯 CSS 图表占位,
BizChart / BizRankList 可直接替换)。<script setup lang="ts">
/** 场景:综合数据大屏——标题栏 + 指标带 + 环图 / 柱图 / 排行三栏编排(纯 CSS 图表占位) */
import { BizRankList, BizScreenContainer } from 'vue3-ep-biz-lib'
import type { BizRankItem } from 'vue3-ep-biz-lib'
const kpis = [
{ label: '今日产值', value: '3,842万', trend: '+12.4%' },
{ label: '能耗强度', value: '0.42吨', trend: '-3.1%' },
{ label: '开工率', value: '91.6%', trend: '+0.8%' },
{ label: '安全运行', value: '326天', trend: '持平' },
]
const bars = [42, 68, 55, 88, 74, 96, 61, 83]
const ranks: BizRankItem[] = [
{ label: '智能制造事业部', value: 1286 },
{ label: '新能源事业部', value: 1043 },
{ label: '生物医药园', value: 872 },
{ label: '数字服务基地', value: 691 },
{ label: '新材料中心', value: 528 },
]
</script>
<template>
<div style="height: 420px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer :width="1920" :height="1080">
<div
style="
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
color: #e2e8f0;
background:
radial-gradient(900px 420px at 20% 0%, rgba(59, 130, 246, 0.16), transparent 60%),
radial-gradient(900px 420px at 80% 0%, rgba(45, 212, 191, 0.12), transparent 60%),
linear-gradient(180deg, #0a1220, #0c1730);
"
>
<!-- 标题栏 -->
<div
style="
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 96px;
border-bottom: 1px solid rgba(125, 211, 252, 0.22);
background: linear-gradient(180deg, rgba(125, 211, 252, 0.1), transparent);
"
>
<span style="font-size: 40px; font-weight: 700; letter-spacing: 8px">园区经济运行总览</span>
<span
style="
position: absolute;
right: 40px;
font-size: 16px;
opacity: 0.6;
letter-spacing: 2px;
"
>
数据周期:2026-09
</span>
</div>
<!-- 指标带 -->
<div style="display: flex; gap: 16px; padding: 16px 32px">
<div
v-for="k in kpis"
:key="k.label"
style="
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 20px;
border: 1px solid rgba(125, 211, 252, 0.22);
border-radius: 8px;
background: rgba(125, 211, 252, 0.06);
"
>
<span style="font-size: 17px; opacity: 0.7">{{ k.label }}</span>
<span style="display: flex; align-items: baseline; gap: 10px">
<span style="font-size: 26px; font-weight: 700; color: #7dd3fc">{{ k.value }}</span>
<span
:style="{
fontSize: '14px',
color: k.trend.startsWith('-') ? '#34d399' : k.trend === '持平' ? '#94a3b8' : '#fbbf24',
}"
>
{{ k.trend }}
</span>
</span>
</div>
</div>
<!-- 三栏图表区 -->
<div style="flex: 1; display: flex; gap: 16px; padding: 0 32px 24px; min-height: 0">
<!-- 环图占位(conic-gradient) -->
<div
style="
width: 380px;
display: flex;
flex-direction: column;
gap: 10px;
border: 1px solid rgba(125, 211, 252, 0.22);
border-radius: 10px;
padding: 16px;
background: rgba(13, 26, 48, 0.6);
"
>
<span style="font-size: 18px">产业结构占比</span>
<div style="flex: 1; display: flex; align-items: center; justify-content: center; gap: 28px">
<div
style="
width: 190px;
height: 190px;
border-radius: 50%;
background: conic-gradient(#38bdf8 0 42%, #34d399 42% 68%, #fbbf24 68% 86%, #64748b 86% 100%);
mask: radial-gradient(circle, transparent 58px, #000 59px);
-webkit-mask: radial-gradient(circle, transparent 58px, #000 59px);
"
/>
<div style="display: flex; flex-direction: column; gap: 10px; font-size: 15px">
<span><i style="display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: #38bdf8; margin-right: 8px" />智能制造 42%</span>
<span><i style="display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: #34d399; margin-right: 8px" />新能源 26%</span>
<span><i style="display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: #fbbf24; margin-right: 8px" />生物医药 18%</span>
<span><i style="display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: #64748b; margin-right: 8px" />其他 14%</span>
</div>
</div>
</div>
<!-- 柱图占位(flex 高度) -->
<div
style="
flex: 1;
display: flex;
flex-direction: column;
gap: 10px;
border: 1px solid rgba(125, 211, 252, 0.22);
border-radius: 10px;
padding: 16px;
background: rgba(13, 26, 48, 0.6);
"
>
<span style="font-size: 18px">月度产值走势(亿元)</span>
<div style="flex: 1; display: flex; align-items: flex-end; gap: 6%; padding: 0 4%">
<div
v-for="(b, i) in bars"
:key="i"
:style="{
flex: 1,
height: b + '%',
borderRadius: '4px 4px 0 0',
background: 'linear-gradient(180deg, #38bdf8, rgba(56, 189, 248, 0.25))',
}"
/>
</div>
</div>
<!-- 排行榜 -->
<div
style="
width: 420px;
display: flex;
flex-direction: column;
gap: 10px;
border: 1px solid rgba(125, 211, 252, 0.22);
border-radius: 10px;
padding: 16px;
background: rgba(13, 26, 48, 0.6);
"
>
<span style="font-size: 18px">部门产值 TOP5</span>
<BizRankList :data="ranks" :top="5" />
</div>
</div>
</div>
</BizScreenContainer>
</div>
</template>
显示代码
内容编排
园区经济运行监测
图表区(BizChart 可直接放入,随容器缩放自适应)
区域产值排行
196,420
高新区
278,150
经开区
361,230
科创城
443,870
临港区
设计稿内固定坐标布局:标题 + 图表占位 + 排行榜(
BizChart / BizRankList 可直接放入,随容器缩放一致)。<script setup lang="ts">
/** 场景:内容编排——设计稿内固定坐标布局(图表 + 排行组合),缩放后整体一致 */
import { ElCard } from 'element-plus'
import { BizRankList, BizScreenContainer } from 'vue3-ep-biz-lib'
import type { BizRankItem } from 'vue3-ep-biz-lib'
const ranks: BizRankItem[] = [
{ label: '高新区', value: 96420 },
{ label: '经开区', value: 78150 },
{ label: '科创城', value: 61230 },
{ label: '临港区', value: 43870 },
]
</script>
<template>
<div style="height: 380px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer :width="1280" :height="720">
<div style="width: 100%; height: 100%; padding: 32px; box-sizing: border-box; display: flex; gap: 24px; color: #e2e8f0">
<div style="flex: 1; display: flex; flex-direction: column; gap: 16px">
<div style="font-size: 34px; font-weight: 700; letter-spacing: 4px">园区经济运行监测</div>
<div style="flex: 1; background: rgba(56, 189, 248, 0.08); border: 1px solid rgba(56, 189, 248, 0.25); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 22px; opacity: 0.8">
图表区(BizChart 可直接放入,随容器缩放自适应)
</div>
</div>
<ElCard style="width: 340px; background: rgba(15, 23, 42, 0.85); border-color: rgba(56, 189, 248, 0.25)" shadow="never">
<template #header>
<span style="font-size: 16px; color: #e2e8f0">区域产值排行</span>
</template>
<BizRankList :data="ranks" :top="4" />
</ElCard>
</div>
</BizScreenContainer>
</div>
</template>
显示代码
拉伸填满
卡片 1
卡片 2
卡片 3
mode="stretch" 宽高各自缩放铺满(比例不一致时变形,无留边)。<script setup lang="ts">
/** 场景:拉伸填满——stretch 模式宽高各自缩放(比例不一致时变形,铺满无黑边) */
import { BizScreenContainer } from 'vue3-ep-biz-lib'
</script>
<template>
<div style="height: 300px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer :width="1920" :height="1080" mode="stretch">
<div
style="
width: 100%;
height: 100%;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
padding: 40px;
box-sizing: border-box;
"
>
<div v-for="i in 3" :key="i" style="border: 2px dashed rgba(125, 211, 252, 0.4); border-radius: 12px; display: flex; align-items: center; justify-content: center; color: #7dd3fc; font-size: 30px">
卡片 {{ i }}
</div>
</div>
</BizScreenContainer>
</div>
</template>
显示代码
缩放比监控
缩放比 1.000容器 0 × 0expose:-
拖动浏览器窗口大小观察缩放比变化
resize 事件外抛缩放系数与容器尺寸;expose getScale 供交互换算(如地图坐标)。<script setup lang="ts">
/** 场景:缩放比监控——resize 事件外抛当前缩放系数与容器尺寸 */
import { ref } from 'vue'
import { ElTag } from 'element-plus'
import { BizScreenContainer } from 'vue3-ep-biz-lib'
import type { BizScreenContainerInstance } from 'vue3-ep-biz-lib'
const info = ref({ scale: 1, width: 0, height: 0 })
const refEl = ref<BizScreenContainerInstance>()
</script>
<template>
<div>
<div style="margin-bottom: 10px; display: flex; gap: 8px; align-items: center">
<ElTag size="small">缩放比 {{ info.scale.toFixed(3) }}</ElTag>
<ElTag size="small" type="info">容器 {{ info.width }} × {{ info.height }}</ElTag>
<ElTag size="small" type="success">expose:{{ refEl?.getScale().toFixed(3) ?? '-' }}</ElTag>
</div>
<div style="height: 300px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer
ref="refEl"
:width="1600"
:height="900"
@resize="(p) => (info = p)"
>
<div style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #7dd3fc; font-size: 30px">
拖动浏览器窗口大小观察缩放比变化
</div>
</BizScreenContainer>
</div>
</div>
</template>
显示代码
容器宽度实时适配
容器宽度
缩放比 1.000容器 0 × 0
等比重排拖动滑杆,容器尺寸变化实时触达缩放与 resize 事件
滑杆改变容器宽度,
ResizeObserver 实时驱动重排缩放并外抛最新 resize 载荷(无需调整浏览器窗口)。<script setup lang="ts">
/** 场景:容器尺寸实时适配——滑杆改变容器宽度,内容等比重排并外抛最新缩放比 */
import { ref } from 'vue'
import { ElSlider, ElTag } from 'element-plus'
import { BizScreenContainer } from 'vue3-ep-biz-lib'
const widthPercent = ref(100)
const info = ref({ scale: 1, width: 0, height: 0 })
</script>
<template>
<div>
<div style="margin-bottom: 10px; display: flex; align-items: center; gap: 12px; max-width: 520px">
<span style="font-size: 13px; flex-shrink: 0">容器宽度</span>
<ElSlider v-model="widthPercent" :min="40" :max="100" :step="1" />
</div>
<div style="margin-bottom: 10px; display: flex; gap: 8px">
<ElTag size="small">缩放比 {{ info.scale.toFixed(3) }}</ElTag>
<ElTag size="small" type="info">容器 {{ info.width }} × {{ info.height }}</ElTag>
</div>
<div
:style="{
height: '320px',
width: widthPercent + '%',
border: '1px solid #e4e7ed',
borderRadius: '4px',
overflow: 'hidden',
transition: 'width 0.1s linear',
}"
>
<BizScreenContainer :width="1600" :height="900" @resize="(p) => (info = p)">
<div
style="
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 14px;
color: #7dd3fc;
background: linear-gradient(180deg, #0b1628, #0d1a30);
"
>
<span style="font-size: 40px; font-weight: 700; letter-spacing: 6px">等比重排</span>
<span style="font-size: 18px; opacity: 0.7">拖动滑杆,容器尺寸变化实时触达缩放与 resize 事件</span>
</div>
</BizScreenContainer>
</div>
</div>
</template>
显示代码
全屏投放
全屏投放
应急指挥大屏
全屏后等比铺满整屏(按 Esc 退出)
配合
BizFullScreen 一键全屏(Esc 退出后恢复等比适配)。<script setup lang="ts">
/** 场景:全屏大屏——配合 BizFullScreen 一键全屏投放 */
import { BizFullScreen, BizScreenContainer } from 'vue3-ep-biz-lib'
</script>
<template>
<div>
<div style="margin-bottom: 10px">
<BizFullScreen target="#biz-screen-fullscreen-target">全屏投放</BizFullScreen>
</div>
<div id="biz-screen-fullscreen-target" style="height: 340px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer :width="1920" :height="1080">
<div style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 18px; color: #7dd3fc">
<div style="font-size: 48px; font-weight: 700; letter-spacing: 6px">应急指挥大屏</div>
<div style="font-size: 20px; opacity: 0.75">全屏后等比铺满整屏(按 Esc 退出)</div>
</div>
</BizScreenContainer>
</div>
</div>
</template>
显示代码
左上对齐
左上角对齐(拼接屏从左至右铺设)
center=false 从左上角开始缩放(拼接屏从左至右铺设场景)。<script setup lang="ts">
/** 场景:居中与左上——center 关闭后从左上角开始缩放(拼接屏场景) */
import { BizScreenContainer } from 'vue3-ep-biz-lib'
</script>
<template>
<div style="height: 300px; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden">
<BizScreenContainer :width="960" :height="540" :center="false">
<div
style="
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(56, 189, 248, 0.15), rgba(59, 130, 246, 0.1));
border-right: 2px solid rgba(56, 189, 248, 0.5);
display: flex;
align-items: center;
justify-content: center;
color: #7dd3fc;
font-size: 24px;
"
>
左上角对齐(拼接屏从左至右铺设)
</div>
</BizScreenContainer>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| width | number | 1920 | 设计稿宽度 |
| height | number | 1080 | 设计稿高度 |
| mode | 'fit' | 'stretch' | 'fit' | 适配模式:等比居中 / 拉伸填满 |
| center | boolean | true | 缩放原点居中定位(false 从左上角开始) |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| resize | ({ scale, width, height }) | 容器尺寸变化(缩放系数随之变化时触发) |
Slots
| 插槽名 | 说明 |
|---|---|
| default | 大屏内容(按设计稿尺寸编排) |
Expose
| 名称 | 类型 | 说明 |
|---|---|---|
| getScale | () => number | 当前缩放系数 |
| getContainerSize | () => { width, height } | 容器实际尺寸 |
TIP
容器需有确定高度(父级 100% / 固定 px);缩放后 BizChart 等 ResizeObserver 型组件自动重绘。涉及绝对坐标交互(点击换算)时按 getScale() 换算。