@hooksvue/big-screen
v0.1.1
Published
A lightweight Vue 3 big-screen adaptation library — global plugin + container component dual-mode.
Downloads
119
Maintainers
Readme
@hooksvue/big-screen
一个轻量、零 UI 依赖的 Vue 3 大屏自适应库,提供 JS 计算 与 纯 CSS 双技术方案。
English README · 更新日志 / Changelog
- 🎯 双技术方案 ——
ScreenResizer(JS 动态控制) +css-only.css(0 JS /tan(atan2)) - 🎮 双驱动模式 —— 全局插件一键接管 + 容器组件局部适配
- 🧩 Vue 解耦 —— 核心类纯 JS,可在 React / 原生项目使用
- 📦 JS 与 CSS 完全分离 ——
style.css与css-only.css独立产物,按需引入 - 🛠 运行时可调 ——
update()/resize()/destroy()全暴露 - 🪶 极致轻量 —— ESM gzip < 2 KB,纯 CSS < 1 KB
- 💻 技术栈 —— Vite 8 / TypeScript 6 / Vue 3.5 / pnpm
安装
pnpm add @hooksvue/big-screen
# or: npm i / yarn addvue 是 peerDependency,需要项目自身已经安装 vue@^3.5.0。
快速上手
方式 A:JS 计算模式(推荐)
A1. 全局插件 —— 单页大屏一键接管
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { createBigScreen } from '@hooksvue/big-screen';
import '@hooksvue/big-screen/style.css';
createApp(App)
.use(createBigScreen({
el: '#app',
width: 1920,
height: 1080,
mode: 'fit',
}))
.mount('#app');A2. 容器组件 —— 局部内嵌大屏
<script setup lang="ts">
import { useTemplateRef } from 'vue';
import { BigScreenContainer } from '@hooksvue/big-screen';
import type { ScaleInfo } from '@hooksvue/big-screen';
import '@hooksvue/big-screen/style.css';
const bsRef = useTemplateRef<{ resize(): void; destroy(): void }>('bs');
function onResize(info: ScaleInfo) {
console.log('当前缩放', info.scaleX, info.parentWidth);
}
</script>
<template>
<BigScreenContainer
ref="bs"
:width="1920"
:height="1080"
mode="fit"
background="#000"
@resize="onResize"
>
<!-- 内容根节点必须 width:100%; height:100% -->
<YourDashboard />
</BigScreenContainer>
</template>A3. 纯 JS 内核(脱离 Vue)
import { ScreenResizer } from '@hooksvue/big-screen';
const r = new ScreenResizer({
target: document.querySelector('#screen')!,
width: 1920,
height: 1080,
mode: 'fit',
onResize: (info) => console.log(info),
});
r.start();
// 运行时改参数
r.update({ mode: 'stretch' });
// 手动触发重算
r.resize();
// 销毁
r.destroy();A4. v-scale 指令 —— 图表元素监听缩放
createBigScreen() 会默认注册全局指令;按需使用时也可以手动注册:
import { vScale } from '@hooksvue/big-screen';
createApp(App).directive('scale', vScale).mount('#app');<template>
<!-- 使用方法一:例如 echarts 容器,自动写入 CSS 变量并派发 adapt-scale 事件 -->
<div ref="echartsRef" style="width: 500px;height: 400px;" v-scale />
<!-- 使用方法二:传入监听函数 -->
<div ref="echartsRef" style="width: 500px;height: 400px;" v-scale="handlerAdaptScale" />
</template>
<script>
export default {
methods: {
handlerAdaptScale(el, scale) {
// do sth...
},
},
};
</script>方式 B:纯 CSS 模式(0 JS)
// main.ts 只需引入 CSS,无任何 JS
import '@hooksvue/big-screen/css-only.css';<!-- 全屏:基于 viewport (vw/vh) -->
<div class="hbs-css-viewport" style="--hbs-w:1920;--hbs-h:1080;">
<div class="hbs-css-content">
<!-- 设计稿尺寸的内容 -->
</div>
</div>
<!-- 容器:基于父容器 (container queries: cqw/cqh) -->
<div class="hbs-css-container" style="--hbs-w:1920;--hbs-h:1080;">
<div class="hbs-css-content">…</div>
</div>
<!-- 切换缩放模式:默认 fit;其他在 .hbs-css-content 上加修饰类 -->
<div class="hbs-css-content hbs-mode-stretch">…</div>
<div class="hbs-css-content hbs-mode-fill-width">…</div>
<div class="hbs-css-content hbs-mode-fill-height">…</div>原理:CSS tan(atan2(100vw, 1920px)) 把长度比转成无单位数字,再喂给 transform: scale()。
浏览器要求:Chrome 111+ / Safari 15.4+ / Firefox 108+。
API
<BigScreenContainer /> Props / Events / Exposed
| Prop | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| width | number | 1920 | 设计稿宽 |
| height | number | 1080 | 设计稿高 |
| mode | ScaleMode | 'fit' | 缩放模式 |
| delay | number | 80 | resize 防抖 ms |
| background | string | '#000' | 外层填充色(黑边色) |
| Event | 载荷 |
|-------|------|
| resize | ScaleInfo |
| 通过 ref 暴露的方法 | 说明 |
|-----------------------|------|
| resize() | 立即重算缩放 |
| destroy() | 销毁底层引擎 |
| getResizer() | 获取底层 ScreenResizer 实例 |
createBigScreen(options) 全局插件
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| el | string | '#app' | 接管的根选择器 |
| width / height | number | 1920 / 1080 | 设计稿尺寸 |
| mode | ScaleMode | 'fit' | 缩放模式 |
| delay | number | 80 | 防抖 ms |
| registerComponent | boolean | true | 是否同时全局注册 <BigScreenContainer /> |
| registerDirective | boolean | true | 是否同时全局注册 v-scale |
v-scale 指令
| 用法 | 说明 |
|------|------|
| v-scale | 监听元素有效缩放,写入 --hbs-adapt-scale / --hbs-adapt-scale-x / --hbs-adapt-scale-y |
| v-scale="handler" | 缩放变化时调用 handler(el, scale, info) |
info 类型为 { scaleX: number; scaleY: number; scale: number },并会同步派发 adapt-scale 自定义事件。
ScreenResizer 类
new ScreenResizer({
target: HTMLElement, // 必填,被缩放元素
parent?: HTMLElement, // 可选,参考容器;不传则用 window
width?: 1920,
height?: 1080,
mode?: 'fit',
delay?: 80,
onResize?: (info: ScaleInfo) => void,
});| 方法 | 说明 |
|------|------|
| start() | 启动监听并立即缩放一次 |
| resize() | 同步触发一次缩放 |
| update(opts) | 运行时更新 width/height/mode/delay/onResize |
| destroy() | 销毁监听并还原内联样式 |
缩放模式 ScaleMode
| 值 | 行为 | 典型场景 |
|----|------|---------|
| fit | 等比缩放,取宽高比例最小值,留黑边 | 通用大屏(默认) |
| stretch | 非等比拉伸,宽高分别撑满 | 接受轻微变形 |
| fillWidth | 等比,以宽度为基准撑满 | 强调"满宽",可垂直滚动 |
| fillHeight | 等比,以高度为基准撑满 | 强调"满高" |
常见陷阱(务必阅读)
1. 内容根节点必须 width:100%; height:100%
库会把 .hbs-content 这一层的宽高设置为设计稿尺寸(如 1920×1080),你的内容放进去之后,根节点必须撑满父级,否则改设计稿尺寸(如切到 4K)时内容会缩在左上角。
/* ❌ 错误 */
.dashboard { width: 1920px; height: 1080px; }
/* ✅ 正确 */
.dashboard { width: 100%; height: 100%; }2. JS 模式的居中算法
不使用 translate(-50%,-50%) scale() 这种和 scale 复合误差大的写法(autofit 弹窗/地图偏移的根源)。本库用 transformOrigin: '0 0' + translate(tx, ty) 显式计算偏移,未来做弹窗/地图修正时坐标可被精确反推。
3. echarts 等图表缩放监听
JS 模式下 transform: scale() 容器内的图表如果需要感知缩放,可在图表根节点上使用 v-scale,通过 CSS 变量、adapt-scale 事件或 handler(el, scale, info) 做自定义适配。
本地开发
pnpm install
pnpm dev # 启动 playground (http://localhost:5174)
pnpm build # 库构建(输出到 dist/)
pnpm build:watch # 库 watch 模式(联调外部项目)
pnpm type-check # vue-tsc 类型检查pnpm dev 启动的 playground 是一个完整的商业大屏 demo(运营数据监控中心),包含:
- 顶部标题 + 实时时钟
- 6 张 KPI 卡片
- 6 个 echarts 图表(折线 / 柱状 / 饼图 / 雷达 / 仪表盘 / 横向条形)
- 数据表格
- 右侧属性面板 —— 实时调参 + 方法调用按钮 + API 速查
- 可拖拽缩放的 holder 容器 —— 直观验证父容器变化时的适配能力
- JS / 纯 CSS 双技术 Tab —— 一键切换对比
仓库
- GitHub: https://github.com/mhxy13867806343/vue3-Adaptive-Large-Screen-ts
- Gitee: https://gitee.com/fangjiayu/vue3-adaptive-large-screen-ts
License
MIT © hooksvue
