vue左右div结构手动拉伸并且echarts图表根据拉伸宽高自适应

需求:

  1. 左右结构的div,可以根据数据抬起按下进行拉伸修改容器宽度的操作
  2. 给左右结构某一图表设置拉伸自适应
  3. 左右结构都设置个最小宽度,只能到一定区域内拉伸
  4. 解决echarts的bug(重复加载chart实例):[ECharts] There is a chart instance already initialized on the dom.
  5. 解决浏览器兼容性报错问题

       5.解决echarts在flex布局下宽高不显示问题

1.效果

 2.左右结构布局

左右布局给定一个基础的宽度,并且给最小宽度,min-width,如果不给最小宽度,那么拉伸的时候会拉到底,到时候其他元素挤压或者是隐藏了就不太好

<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <!-- echarts图标区 -->
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 300,
            rightWidth: 400
        };
    },
    mounted() {},
    methods: {}
};
</script>

<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
        background-color: #ddd;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        background-color: #d3e2d1;
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

效果如下:

 3.拉伸效果实现

  1. 首先下载echarts,不用多说,下载最新版就行
npm install echarts -S

     2.局部导入和全局导入,根据自己的需求来

局部导入:在需要用到的页面导入即可,为了各位看的更明白我用的是局部导入的方式

import * as echarts from 'echarts';

全局导入:在main.js文件导入挂载

import echarts from 'echarts';
Vue.prototype.$echarts = echarts;

全局导入后在页面使用:

this.$echarts.方法名

        3.在中间灰色区域添加个鼠标按下事件

<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center" @mousedown="onMouseDown"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <!-- echarts图标区 -->
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 200,
            rightWidth: 400
        };
    },
    mounted() {},
    methods: {
        onMouseDown() {
            // 鼠标按下时开始拖动
            this.isResizing = true;

            // 监听鼠标移动事件
            document.addEventListener('mousemove', this.onMouseMove);
            // 监听鼠标松开事件
            document.addEventListener('mouseup', this.onMouseUp);
        },
        onMouseMove(event) {
            if (this.isResizing) {
                // 计算鼠标在容器中的位置
                const containerRect = this.$el.getBoundingClientRect();
                const mouseX = event.clientX - containerRect.left;

                // 更新左侧和右侧容器的宽度
                this.leftWidth = mouseX;
                this.rightWidth = this.containerWidth - mouseX;
            }
        },
        onMouseUp() {
            // 鼠标松开时停止拖动
            this.isResizing = false;

            // 移除监听鼠标移动和松开事件
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        }
    }
};
</script>

<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
        background-color: #ddd;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        background-color: #d3e2d1;
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

效果:

 3.添加echarts图表

如果是按照以前的办法,不能实现自适应的哈,只能说把图标显示出来了,但是在拉伸的时候折线图不能自适应。

解决echarts的bug(重复加载chart实例)关键代码如下:

  if (
                    //判断是否存在echarts实例化对象,如果存在则销毁
                    this.chartsDom != null &&
                    this.chartsDom != '' &&
                    this.chartsDom != undefined
                ) {
                    this.chartsDom.dispose();
                }
<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center" @mousedown="onMouseDown"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <!-- echarts图标区 -->
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import * as echarts from 'echarts';
export default {
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 200,
            rightWidth: 400
        };
    },
    mounted() {
        this.echartsDom();
    },
    methods: {
        echartsDom() {
            // 基于准备好的dom,初始化echarts实例
            this.$nextTick(_ => {
                if (
                    //判断是否存在echarts实例化对象,如果存在则销毁
                    this.chartsDom != null &&
                    this.chartsDom != '' &&
                    this.chartsDom != undefined
                ) {
                    this.chartsDom.dispose();
                }
                const dom = document.getElementById('myChat');
                dom.style.width = dom.parentNode.parentNode.clientWidth + 'px';
                this.chartsDom = echarts.init(dom); //创建echarts实例化对象
                this.chartsDom.clear(); //清空画布数据
                //设置对应的参数,标题,x轴,y轴坐标,以及显示的数据
                let options = {
                    xAxis: {
                        type: 'category',
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [
                        {
                            data: [820, 932, 901, 934, 1290, 1330, 1320],
                            type: 'line',
                            smooth: true
                        }
                    ]
                };
                this.chartsDom.setOption(options);
                this.chartsDom.resize();
                setTimeout(function() {
                    window.addEventListener('resize', () => {
                        this.chartsDom.resize();
                    });
                }, 200);
            });
        },
        onMouseDown() {
            // 鼠标按下时开始拖动
            this.isResizing = true;

            // 监听鼠标移动事件
            document.addEventListener('mousemove', this.onMouseMove);
            // 监听鼠标松开事件
            document.addEventListener('mouseup', this.onMouseUp);
        },
        onMouseMove(event) {
            if (this.isResizing) {
                // 计算鼠标在容器中的位置
                const containerRect = this.$el.getBoundingClientRect();
                const mouseX = event.clientX - containerRect.left;

                // 更新左侧和右侧容器的宽度
                this.leftWidth = mouseX;
                this.rightWidth = this.containerWidth - mouseX;
            }
        },
        onMouseUp() {
            // 鼠标松开时停止拖动
            this.isResizing = false;

            // 移除监听鼠标移动和松开事件
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        }
    }
};
</script>

<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
        background-color: #ddd;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        background-color: #d3e2d1;
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

效果:

 4.解决echarts图表没有根据拉伸自适应问题(完整代码)

1.下载element-resize-detector

npm install element-resize-detector -S

2.局部导入

var elementResizeDetectorMaker = require('element-resize-detector');

3.完整代码如下:

<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center" @mousedown="onMouseDown"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
//elementResizeDetectorMaker,该全局函数是使元素调整大小检测器实例的maker函数。
var elementResizeDetectorMaker = require('element-resize-detector');
import * as echarts from 'echarts';
export default {
    name: 'Index',
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 200,
            rightWidth: 400,
            chartsDom: null
        };
    },
    mounted() {
        this.changeEchartsWidthApi();
    },
    methods: {
        //监听盒子大小,改变echarts宽度,实现echarts自适应
        changeEchartsWidthApi() {
            // 创建实例,无参数
            var erd = elementResizeDetectorMaker(); //使用默认选项(将使用基于对象的方法)
            // 创建实例带参数
            // 使用基于超快速滚动的方法。
            // 这是推荐的策略。
            var erdUltraFast = elementResizeDetectorMaker({
                strategy: 'scroll',
                callOnAdd: true, //callOnAdd选项,用于确定在添加侦听器时是否应调用它们。默认为true。
                //如果为true,则确保在添加侦听器后将对其进行调用。如果为false,则在添加侦听器时将不保证其
                //被调用(不会阻止其被调用)
                debug: true
            });
            //监听class为staticNextMain的元素 大小变化
            var self = this;
            //侦听元素的调整大小事件,并使用元素作为调整大小事件的参数来调用侦听器函数。传递给函数的选项将
            //覆盖实例选项
            erd.listenTo(document.getElementById('echartsWarp'), function(element) {
                self.ChartsApi();
            });
        },
        ChartsApi() {
            // 基于准备好的dom,初始化echarts实例
            this.$nextTick(_ => {
                if (
                    //判断是否存在echarts实例化对象,如果存在则销毁
                    this.chartsDom != null &&
                    this.chartsDom != '' &&
                    this.chartsDom != undefined
                ) {
                    this.chartsDom.dispose();
                }
                const dom = document.getElementById('myChat');
                dom.style.width = dom.parentNode.parentNode.clientWidth + 'px';
                this.chartsDom = echarts.init(dom); //创建echarts实例化对象
                this.chartsDom.clear(); //清空画布数据
                //设置对应的参数,标题,x轴,y轴坐标,以及显示的数据
                let options={
                    xAxis: {
                        type: 'category',
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [
                        {
                            data: [820, 932, 901, 934, 1290, 1330, 1320],
                            type: 'line',
                            smooth: true
                        }
                    ]
                }
                this.chartsDom.setOption(options);
                this.chartsDom.resize();
                setTimeout(function() {
                    window.addEventListener('resize', () => {
                        this.chartsDom.resize();
                    });
                }, 200);
            });
        },
        onMouseDown() {
            // 鼠标按下时开始拖动
            this.isResizing = true;

            // 监听鼠标移动事件
            document.addEventListener('mousemove', this.onMouseMove);
            // 监听鼠标松开事件
            document.addEventListener('mouseup', this.onMouseUp);
        },
        onMouseMove(event) {
            if (this.isResizing) {
                // 计算鼠标在容器中的位置
                const containerRect = this.$el.getBoundingClientRect();
                const mouseX = event.clientX - containerRect.left;

                // 更新左侧和右侧容器的宽度
                this.leftWidth = mouseX;
                this.rightWidth = this.containerWidth - mouseX;
            }
        },
        onMouseUp() {
            // 鼠标松开时停止拖动
            this.isResizing = false;

            // 移除监听鼠标移动和松开事件
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        }
    }
};
</script>
<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

文章到此结束,希望对你有所帮助~

猜你喜欢

转载自blog.csdn.net/qq_44278289/article/details/132226446
今日推荐