vue3+datav+echarts可视化数据大屏 (适配各种尺寸屏幕!)

屏幕适配放弃了rem 方案,使用更通用的 css3:scale 缩放方案,项目的基准尺寸是 1920px*1080px,所以支持用比例屏幕 100% 填充,如果非同比例则会自动计算比例居中填充,不足的部分则留白。得适配方案不能试图您的场景,则可以自行修改方案。

大屏采用的是moke数据,后续在真实项目中将moke接口替换成真实接口即可,大屏算是一个基础的框架,但是在真实项目中使用也是没什么问题的,在文章结尾处会贴出git

由于datav 的vue3版本运行时会报错,这里我也没有去细究这个报错原因,所以这里替换成封装后的data,除了每个内置组件的名称不一样,组件的配置都是一样的,后续如果要更换datav时,直接将组件的名称更换即可

效果图

1,下载插件

pnpm i @kjgl77/datav-vue3 -save

pnpm i axios -save

pnpm i echarts -save

2. 添加容器组件

我的做法是,将一个vue文件做为容器文件,在这个文件里,将我们框架分好。然后在将其他内容通过组件的方式写入到容器组件里,适配容器组件一定要放在最外层。

javascript 复制代码
<template>
    <AdaptiveView>
        <dv-border-box11 title="香蕉麻花皮测试" :title-width="400" :animate="false" class="box-title">
            <!-- 上部分 -->
            <div class="box">
                <div>
                    <dv-border-box1 class="frame">
                        <dv-loading v-if="loading1"></dv-loading>
                        <IndexData1 :data="data1.list" v-else></IndexData1>
                    </dv-border-box1>
                </div>
                <div>
                    <dv-border-box2 class="frame">
                        <IndexData2></IndexData2>
                    </dv-border-box2>

                </div>
                <div>
                    <dv-border-box3 class="frame">
                        <IndexData3></IndexData3>
                    </dv-border-box3>

                </div>
            </div>
            <!-- 中部分 -->
            <div class="box">
                <div>
                    <dv-border-box4 class="frame">
                        <IndexData4></IndexData4>
                    </dv-border-box4>

                </div>
                <div>
                    <dv-border-box5 class="frame">
                        <IndexData5></IndexData5>
                    </dv-border-box5>
                </div>
                <div>
                    <dv-border-box6 class="frame">
                        <IndexData6></IndexData6>
                    </dv-border-box6>

                </div>
            </div>
            <!-- 下部分 -->
            <div class="box">
                <div>
                    <dv-border-box7 class="frame">
                        <IndexData7></IndexData7>
                    </dv-border-box7>

                </div>
                <div>
                    <dv-border-box8 class="frame">
                        <IndexData8></IndexData8>
                    </dv-border-box8>

                </div>
                <div>
                    <dv-border-box9 class="frame">
                        <IndexData9></IndexData9>
                    </dv-border-box9>

                </div>
            </div>
        </dv-border-box11>
    </AdaptiveView>
</template>
<script lang="ts">
import { ref, onMounted,reactive } from "vue"
import IndexData1 from './IndexData1.vue';
import IndexData2 from './IndexData2.vue';
import IndexData3 from './IndexData3.vue';
import IndexData4 from './IndexData4.vue';
import IndexData5 from './IndexData5.vue';
import IndexData6 from './IndexData6.vue';
import IndexData7 from './IndexData7.vue';
import IndexData8 from './IndexData8.vue';
import IndexData9 from './IndexData9.vue';
import AdaptiveView from '@/components/AdaptiveView.vue';
import { info } from './api';

export default {
    setup() {
        const loading1 = ref(true)

        let data1:any = reactive({
            list: ""
        })

        const getdata = async () => {
            const {data} = await info();
            console.log(123)
            loading1.value=false
            data1.list = data.data
        };
        onMounted(()=>{
        setInterval(()=>{
            getdata()
        },360000)
            
        })
        return {
            data1,loading1
        }
    },

    components: {
        AdaptiveView, IndexData1, IndexData2, IndexData3, IndexData4, IndexData5, IndexData6, IndexData7, IndexData8, IndexData9
    }
}
</script>
<style scoped>
.box {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.frame {
    height: 320px;
    width: 625px;
    margin-top: 20px;
}

.box-title {
    padding-top: 40px;
    padding-left: 20px;
    padding-right: 20px;
}
</style>

3. 适配组件

通过插槽将容器组件放入,通过对不同的分辨率进行等比例的缩小或放大,当不满足比例时进行留白处理

javascript 复制代码
<template>
    <div class="ScreenAdapter" :style="style">
        <slot />
    </div>
</template>
<script lang="ts">
import { onMounted, reactive } from 'vue';
export default {
    props: {
        width: {
            type: String,
            default: '1920'
        },
        height: {
            type: String,
            default: '1080'
        }
    },
    setup(props: any) {
        const style = reactive({
            width: props.width + 'px',
            height: props.height + 'px',
            transform: 'scale(1) translate(-50%, -50%)'
        })
        const Debounce = (fn: any, t: any) => {
            const delay = t || 500
            let timer: any
            return function () {
                const args = arguments
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    timer = null
                    fn.apply(args)
                }, delay)
            }
        }
        // 获取放大缩小比例
        const getScale = () => {
            const w = window.innerWidth / props.width
            const h = window.innerHeight / props.height
            return w < h ? w : h
        }
        // 设置比例
        const setScale = () => {
            style.transform = 'scale(' + getScale() + ') translate(-50%, -50%)'
        }
        onMounted(() => {
            setScale()
            window.onresize = Debounce(setScale, 1000)
        })
        return {
            style
        }
    }

}
</script>
<style scoped>
.ScreenAdapter {
    transform-origin: 0 0;
    position: absolute;
    left: 50%;
    top: 50%;
    transition: 0.3s;

}
</style>

具体使用情况可以查看git仓库的内容

git地址

git@gitee.com:hu-wenwu/vue3-datav-adaptive-version.git

相关推荐
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
虾球xz2 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐3 小时前
前端图像处理(一)
前端
程序猿阿伟3 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒3 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪3 小时前
AJAX的基本使用
前端·javascript·ajax