我一人全干!之vue3后台管理中的大屏展示。

news2024/12/23 7:28:08

使用大屏展示的时候有很多种场景,众多场景都是为了实现大屏自适应。
大屏,顾名思义,就是放在一个固定的屏幕上看的,即使你不做自适应,放在一个固定的屏幕上看也没啥问题,但是很多做大屏的是为了在PC端看,PC端屏幕又是参差不齐的,所以需要做自适应。
毒蘑菇后台管理

方案一:
使用transform的大小缩放来实现,我们先写一个缩放容器AutoScalContainer.vue,代码如下:

<template>
    <div 
        class="auto-scal-container"
        ref="AutoScalContainerRef">
        <div 
            ref="DomRef" 
            class="auto-scal-container-inner">
            <slot></slot>
        </div>
    </div>
</template>

<script>
/** 
 * 自动缩放容器
 * 使用transform进行缩放
 *  */
import { 
    defineComponent,ref,getCurrentInstance,reactive,toRef, 
    computed,onMounted,onActivated,watch,
    onBeforeUnmount,
} from "vue";

export default defineComponent({
    props:{
        width:{
            type:Number,
            default:1920,
        },
        height:{
            type:Number,
            default:1080,
        },
        /** 内部容器的宽高比例 */
        ratio:{
            type:Number,
            default:1920 / 1080,
        },
        /** 
         * fit,原理同img的object-fit
         * contain : 被替换的内容将被缩放,以在填充元素的内容框时保持其宽高比。
         * cover : 被替换的内容在保持其宽高比的同时填充元素的整个内容框。如果对象的宽高比与内容框不相匹配,该对象将被剪裁以适应内容框。
         *  */
        fit:{
            type:String,
            default:'contain',
        },
    },
    emits:['onResizeScreen'],
    setup(props,{emit}){
        const DomRef = ref(null);  //组件实例
        const AutoScalContainerRef = ref(null);  //组件实例
        const dataContainer = reactive({
            height:toRef(props,'height'),
            width:toRef(props,'width'),
            ratio:toRef(props,'ratio'),
            fit:toRef(props,'fit'),
        });
        /** 是否是文档上 */
        function isActive(){
            if(!DomRef.value) return false;
            return DomRef.value.getRootNode() === document;
        }
        /** 自动缩放 */
        function autoResizeScreen(){
            if(!AutoScalContainerRef.value) return;
            if(!DomRef.value) return;
            if(!isActive) return;
            let rect = AutoScalContainerRef.value.getBoundingClientRect();
            let clientWidth = rect.width;
            let clientHeight = rect.height;
            var width = dataContainer.width;
            var height = dataContainer.height;
            let left = 0;
            let top = 0;
            let scale = 0;
            /** 使用外部传入的比例或者传入的宽高计算比例 */
            let ratio = dataContainer.ratio || (width / height);
            // 获取比例  可视化区域的宽高比与 屏幕的宽高比  来进行对应屏幕的缩放
            if(dataContainer.fit == 'contain'){
                if ((clientWidth / clientHeight) > ratio) {
                    scale = clientHeight / height;
                    top = 0;
                    left = (clientWidth - width * scale) / 2;
                } else {
                    scale = clientWidth / width;
                    left = 0;
                    top = (clientHeight - height * scale) / 2;
                }
            }
            if(dataContainer.fit == 'cover'){
                if ((clientWidth / clientHeight) > ratio) {
                    scale = clientWidth / width;
                } else {
                    scale = clientHeight / height;
                }
            }
            // 防止组件销毁后还执行设置状态s
            Object.assign(DomRef.value.style, {
                transform: `scale(${scale})`,
                left: `${left}px`,
                top: `${top}px`,
            });
            /** 向外部通知已经计算缩放 */
            emit('onResizeScreen');
        }
        /** 防抖 */
        let timer_1;
        function fnContainer(){
            clearTimeout(timer_1);
            // timer_1 = setTimeout(()=>{
                autoResizeScreen();
            // },16);
        }
        let timer = setInterval(()=>{
            fnContainer();
        },300);
        onMounted(() => {
            autoResizeScreen();
        });
        window.addEventListener('resize', fnContainer);
        onBeforeUnmount(() => {
            window.removeEventListener('resize', fnContainer);
            window.clearInterval(timer);
        });
        return {
            dataContainer,
            DomRef,
            AutoScalContainerRef,
        };
    },
});
</script>

<style lang="scss" scoped>
.auto-scal-container {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: auto;
    /** 隐藏滚动条 */
    -ms-overflow-style: none;
    scrollbar-width: none;
    &::-webkit-scrollbar {
        display: none;
    }
    >.auto-scal-container-inner {
        overflow: hidden;
        transform-origin: left top;
        z-index: 999;
        width: max-content;
        height: max-content;
        position: absolute;
        top: 0;
        left: 0;
    }
}
</style>

使用方式

<script>
/** 
 * 大屏主页面
 * 采用缩放的形式进行适配,搭配rem的话很方便实用
 *  */
import { defineComponent,ref,getCurrentInstance,reactive,toRef, computed,onMounted,onActivated,watch } from "vue";
import AutoScalContainer from "@/components/AutoScalContainer.vue";
import ViewHead from "./components/ViewHead.vue";
import img_1 from "./assets/bg.png";
import img_2 from "./assets/1-1-bg.png";
import Box_1 from "./components/Box_1.vue";
import Box_2 from "./components/Box_2.vue";
import Box_3 from "./components/Box_3.vue";
import Box_4 from "./components/Box_4.vue";
import Box_5 from "./components/Box_5.vue";
import Box_6 from "./components/Box_6.vue";
import { useRoute } from "vue-router";

export default defineComponent({
    name:'BigScreenView',
    components: {
        AutoScalContainer,
        ViewHead,
        Box_1,
        Box_2,
        Box_3,
        Box_4,
        Box_5,
        Box_6,
    },
    setup(){
        let route = useRoute();
        const dataContainer = reactive({
            loading:false,
            img:{
                img_1,
                img_2,
            },
            fit:'contain',
        }); 
        watch(route,()=>{
            let queryParams = route.query || {};
            let fitMap = {
                'cover':'cover',
                'contain':'contain',
            };
            dataContainer.fit = fitMap[queryParams.fit] || 'contain';
        },{
            immediate:true,
        });
        return {
            dataContainer,
        };
    },
});
</script>

<template>
    <div class="big-screen-view">
        <AutoScalContainer
            :height="1080"
            :width="1920"
            :fit="dataContainer.fit">
            <div 
                class="big-screen-view-container"
                :style="{
                    '--bg-img-1':`url(${dataContainer.img.img_1})`,
                    '--bg-img-2':`url(${dataContainer.img.img_2})`,
                }" >
                <div class="head">
                    <ViewHead
                        title="数据可视化大屏展示"></ViewHead>
                </div>
                <div class="content">
                    <div class="top">
                        <Box_1></Box_1> 
                    </div>
                    <div class="content">
                        <div class="left">
                            <div class="box">
                                <Box_2></Box_2> 
                            </div>
                            <div class="box">
                                <Box_3></Box_3> 
                            </div>
                        </div>
                        <div class="right">
                            <div class="box">
                                <Box_4></Box_4> 
                            </div>
                            <div class="box">
                                <Box_5></Box_5> 
                            </div>
                        </div>
                    </div>
                </div>
                <div class="centre-box">
                    <div class="v-height"></div>
                    <div class="container">
                        <Box_6></Box_6> 
                    </div>
                </div>
            </div>
        </AutoScalContainer>
    </div>
</template>

<style lang="scss" scoped>
.big-screen-view{
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    background-color: #031045c7;
    .big-screen-view-container{
        width: 1920px;
        height: 1080px;
        background-color: rgb(169, 169, 169);
        display: flex;
        flex-direction: column;
        background-image: var(--bg-img-1);
        background-repeat: no-repeat;
        background-size: 100% 100%;
        background-position: center;
        position: relative;
        >.head{
            height: 91px;
            position: relative;
            z-index: 2;
        }
        >.content{
            display: flex;
            flex-direction: column;
            flex: 1 1 0;
            width: 100%;
            height: 0;
            position: relative;
            z-index: 2;
            pointer-events: none;
            >.top{
                width: 100%;
                height: 199px;
                pointer-events: initial;
            }
            >.content{
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                flex: 1 1 0;
                width: 100%;
                height: 0;
                padding: 0 15px 15px 15px;
                box-sizing: border-box;
                >.left,>.right{
                    display: flex;
                    flex-direction: column;
                    >.box{
                        width: 100%;
                        flex: 1 1 0;
                        height: 0;
                        background-image: var(--bg-img-2);
                        background-repeat: no-repeat;
                        background-size: 100% 100%;
                        background-position: center;
                        margin: 0 0 15px 0;
                        pointer-events: initial;
                        &:last-child{
                            margin: 0;
                        }
                    }
                }
                >.left{
                    height: 100%;
                    width: 550px;
                }
                >.right{
                    height: 100%;
                    width: 550px;
                }
            }
        }
        >.centre-box{
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 1;
            display: flex;
            flex-direction: column;
            >.v-height{
                width: 100%;
                height: 270px;
            }
            >.container{
                flex: 1 1 0;
                height: 0;
                width: 100%;
            }
        }
    }
}
</style>

好了,一个用transfor缩放的例子就完成了,使用rem的例子以后为大家讲解
源码
DEMO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1289435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode Hot100 994.腐烂的橘子

题目&#xff1a; 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回…

电商早报 | 12月6日| 1688平台11月GMV增长近25%

1688平台11月GMV增长近25% 12月5日消息&#xff0c;1688发文称&#xff0c;在1688的买家里&#xff0c;25至30岁的“Z世代”占比近50%&#xff0c;30至35岁的“新中产”占比近45%&#xff1b;另外&#xff0c;2023年11月&#xff0c;1688平台GMV增长近25%&#xff0c;日均买家…

菜鸟驿站寄快递真的能省钱吗?还不如去闪侠惠递快递折扣平台下单!

小伙伴们&#xff0c;你们知道我们平常去寄快递发快递的菜鸟驿站是怎么来的吗&#xff1f;今天小编就来带你一探究竟。 那么到菜鸟驿站寄快递真的能省钱吗&#xff1f;其实也不一定。在菜鸟驿站&#xff0c;工作人员称重之后&#xff0c;工作人员说多少就是多少&#xff0c;没…

JavaSE基础50题:6. 求出0~999之间的所有“水仙花数”并输出

概念 “水仙花数”是指一个三位数&#xff0c;其各位数字的立方和确好等于该数本身。 如&#xff1a;153 135333,则153是一个“水仙花数”。 【方法】 如何获得每一位的数&#xff1a;如(153) 个位: 153 % 10 3 十位: 153 / 10 15 15 % 10 5 百位: 153 / 100 1 代码 pu…

Failed to connect to github.com port 443 after 21055 ms: Timed out

目前自己使用了梯*子还是会报这样的错误&#xff0c;连接不到的github。 查了一下原因&#xff1a; 是因为这个请求没有走代理。 解决方案&#xff1a; 设置 -> 网络和Internet -> 代理 -> 编辑 记住这个IP和端口 使用以下命令&#xff1a; git config --global h…

SAP MM 中的业务伙伴确定配置

这篇博客文章将概述 SAP MM 供应商帐户组中的合作伙伴确定是什么以及如何在 S/4 系统中配置它。 本文将指导您完成分步过程&#xff0c;并为您提供有关在供应商主数据中使用合作伙伴确定的完整想法。 合作伙伴角色 供应商在 SAP 中扮演着不同类型的角色&#xff0c;让我们通…

金和OA saveAsOtherFormatServlet接口任意文件上传漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 1. 产品简介 金和数字化智能办公平台&#xff08;简称JC6&#xff09;…

css:flex布局中子元素高度height没有达到100%

目录 问题flex布局示例解决办法方式一方式二 参考 问题 css中使用flex布局中子元素高度height没有达到100% flex布局示例 希望实现两个盒子左右分布&#xff0c;内容垂直居中对齐 <style>.box {display: flex;align-items: center;border: 1px solid #eeeeee;}.box-l…

人事档案管理系统设计与实现

摘 要 进入21世纪&#xff0c;已经步入了信息时代。单位的现代化管理也应该与时俱进。目前&#xff0c;企业的人事档案管理系统信息化已经越来越受到企业的重视。本项目立足于实习调查&#xff0c;严格按照学校毕设的规章制度&#xff0c;做到实事求是。本课题研究目的是&…

推荐一款手持式ECU刷写设备,国产软件配合使用

同星智能开发的一款手持式ECU刷写工具——TF1011&#xff0c;在TSMaster中导入诊断流程即可离线一键刷写。在 PC 端完成配置后&#xff0c;在设备可以在手持式离线场景下实现&#xff1a;基于 UDS 协议的诊断和基于 UDS 协议的 Flash Bootloader 程序更新功能。 产品简介—TF10…

2023-简单点-树莓派中的硬件通讯

树莓派中的通讯方式 串口通讯什么是串口通讯&#xff1f;串口设备的格式串口通讯的特点 tips并行通讯&#xff1f;基于网络的通讯?socket通讯 串口通讯 什么是串口通讯&#xff1f; 串行通信每次传输一个位元数据&#xff0c;并在连续进行单次过程的基础上进行通信。根据数据…

SRMUVS-100VAC-2H2D欠电压监视继电器2常开2常闭35mm导轨安装

系列型号&#xff1a; SRMUVS-58VAC-2H欠电压监视继电器&#xff1b;SRMUVS-100VAC-2H欠电压监视继电器&#xff1b; SRMUVS-110VAC-2H欠电压监视继电器&#xff1b;SRMUVS-220VAC-2H欠电压监视继电器&#xff1b; SRMUVS-58VAC-2H2D欠电压监视继电器&#xff1b;SRMUVS-100…

【MySQL】Linux下如何用语言连接数据库?

用语言连接数据库 前言正式开始创建一个等会专门演示语言连接的库和用户连接mysql要用到的动静态库以及头文件手动下载mysql官方提供的库&#xff08;可以跳过不看&#xff09;下载MySQL时自动安装的库 用C连接数据库官方文档对于编译链接的解释对库的操作函数接口介绍mysql_in…

Python (二) 读写excel文件

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

怎么把拍下来的实体印章公章转为透明电子章,并粘贴到word里面?

用word打开合同文档 插入公章图片&#xff08;jpg/png无所谓&#xff09; 右击图片→裁剪到你爽为止 右击图片→设置图片格式→高度和宽度设置为4厘米&#xff08;具体大小根据你的实际情况来&#xff09; 根据实际情况调整亮度和对比度 设置透明色 将印章衬于文字下方&#xf…

zxjy004- 子模块service及子子模块service_edu搭建

1、新建service module(maven工程&#xff0c;子模块) 1.1 右键 --> new moduel --->选择maven --->完成 1.2. 添加模块类型是 pom 2、引入项目需要的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.…

springboot使用Validator参数校验

引用&#xff1a;https://www.cnblogs.com/yang-yz/p/17576507.html Validator校验框架遵循了 jsr-303验证规范(参数校验规范) JSR : java specification requests 为了解决开发人员在校验参数方面&#xff0c;少写代码 依赖&#xff1a; <dependency><groupId>o…

Navicat 与 华为云 GaussDB 合作再升级,赋能 GaussDB 分布式数据库

2023 年第三季度&#xff0c;Navicat 首次支持了华为云 GaussDB 主备版数据库。经过双方团队进一步的深化合作&#xff0c;Navicat 完成了 GaussDB 分布式的研发适配工作&#xff0c;赋能 GaussDB 全域数据库产品。 GaussDB 数据库分为主备版和分布式版两种模式。主备版适用于…

Java二阶知识点总结(一)Maven

一、Maven概念 Maven是一个项目管理工具&#xff0c;其主要作用有2点 依赖管理&#xff1a;管理项目依赖的各种jar包自动构建&#xff1a;项目构建的过程&#xff0c;从编译、测试、运行、打包到安装的过程可以一键执行 二、Maven工程的目录结构 src/main/java&#xff1a;…

三相电表可以当作高压电表使用吗?

在电力系统中&#xff0c;为了准确测量和计量电能的使用情况&#xff0c;电表起着至关重要的作用。与此同时&#xff0c;为了满足不同电网的需求&#xff0c;各种类型的电表被研发和设计出来。其中&#xff0c;三相电表作为常见的一种类型&#xff0c;广泛应用于低压电网中。但…