1.拖拽布局插件

Vue Grid Layout -️ 适用Vue.js的栅格布局系统可拖动和可调整大小栅格布局的Vue组件。https://jbaysolutions.github.io/vue-grid-layout/zh/

//在package.json中dependencies下添加下面插件库,并执行命令npm install

“vue-grid-layout”:”^3.0.0-beta1″,

2.拖拽页面代码

import { BarChart, FunnelChart, PieChart, RadarChart } from './components';export default {components: {BarChart,FunnelChart,PieChart,RadarChart}};const layout = ref([{ x: 0, y: 0, w: 2, h: 2, i: '0' },{ x: 2, y: 0, w: 2, h: 4, i: '1' },{ x: 4, y: 0, w: 2, h: 5, i: '2' },{ x: 6, y: 0, w: 2, h: 3, i: '3' },{ x: 8, y: 0, w: 2, h: 3, i: '4' },{ x: 10, y: 0, w: 2, h: 3, i: '5' }]);const testLayout = [{x: 0,y: 0,w: 2,h: 8,i: '0',name: 'BarChart'},// {// x: 2,// y: 0,// w: 2,// h: 8,// i: '1',// name: 'FunnelChart'// },// {// x: 4,// y: 0,// w: 2,// h: 8,// i: '2',// name: 'PieChart'// },// {// x: 6,// y: 0,// w: 2,// h: 8,// i: '3',// name: 'RadarChart'// },{x: 8,y: 0,w: 2,h: 8,i: '4',name: 'BarChart'}];layout.value = testLayout;//更新事件(布局更新或栅格元素的位置重新计算)const layoutUpdatedEvent = (newLayout: any) => {console.log('布局更新了');console.log('Updated layout: ', newLayout);layout.value = newLayout;console.log(layout.value);};//移动时的事件const moveEvent = (i: any, newX: any, newY: any) => {console.log('盒子移动了');console.log('MOVE i=' + i + ', X=' + newX + ', Y=' + newY);};//调整大小后的事件/** * * @param i the item id/index * @param newH new height in grid rows * @param newW new width in grid columns * @param newHPx new height in pixels * @param newWPx new width in pixels * */const resizedEvent = (i: any,newH: any,newW: any,newHPx: any,newWPx: any) => {console.log('改变了尺寸');console.log('RESIZED i=' +i +', H=' +newH +', W=' +newW +', H(px)=' +newHPx +', W(px)=' +newWPx);let newLayouts = layout.value.map(item => {console.log(item);console.log(item.i == i);if (item.i == i) {item.Wpx = newWPx + 'px';item.Hpx = newHPx + 'px';}return item;});layout.value = newLayouts;};

3.图表子组件代码

import * as echarts from 'echarts';const props = defineProps({id: {type: String,default: 'barChart'},className: {type: String,default: ''},width: {type: String,default: '100%',required: true},height: {type: String,default: '100%',required: true}});const options = {grid: {left: '2%',right: '2%',// top: '5%',bottom: '10%',containLabel: true},tooltip: {trigger: 'axis',axisPointer: {type: 'cross',crossStyle: {color: '#999'}}},legend: {x: 'center',y: 'bottom',data: ['收入', '毛利润', '收入增长率', '利润增长率'],textStyle: {color: '#999'}},xAxis: [{type: 'category',data: ['浙江', '北京', '上海', '广东', '深圳'],axisPointer: {type: 'shadow'}}],yAxis: [{type: 'value',min: 0,max: 10000,interval: 2000,axisLabel: {formatter: '{value} '}},{type: 'value',min: 0,max: 100,interval: 20,axisLabel: {formatter: '{value}%'}}],series: [{name: '收入',type: 'bar',data: [7000, 7100, 7200, 7300, 7400],barWidth: 20,itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#83bff6' },{ offset: 0.5, color: '#188df0' },{ offset: 1, color: '#188df0' }])}},{name: '毛利润',type: 'bar',data: [8000, 8200, 8400, 8600, 8800],barWidth: 20,itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#25d73c' },{ offset: 0.5, color: '#1bc23d' },{ offset: 1, color: '#179e61' }])}},{name: '收入增长率',type: 'line',yAxisIndex: 1,data: [60, 65, 70, 75, 80],itemStyle: {color: '#67C23A'}},{name: '利润增长率',type: 'line',yAxisIndex: 1,data: [70, 75, 80, 85, 90],itemStyle: {color: '#409EFF'}}]};const initEcharts = () => {console.log('123');echarts.init(document.getElementById(props.id) as HTMLDivElement).dispose(); //先销毁// 图表初始化var chart = echarts.init(document.getElementById(props.id) as HTMLDivElement);chart.setOption(options);// 大小自适应setTimeout(() => {//由于网格布局拖拽放大缩小图表不能自适应,这里设置一个定时器使得echart加载为一个异步过程console.log('111');chart.resize();}, 0);};watch(() => props,(newVal, oldVal) => {console.log('监听传值', newVal);initEcharts();},{deep: true});onMounted(() => {console.log('图表初始化');initEcharts();});.box {width: 100%;height: 100%;background: #fff;}