vue2、vue3分别配置echarts多图表的同步缩放

文章目录

    • ⭐前言
    • ⭐使用dataZoom api实现echart的同步缩放
      • 💖 vue2实现echarts多图表同步缩放
      • 💖 vue3实现echarts多图表同步缩放
    • ⭐结束

⭐前言

大家好!我是yma16,本文分享在vue2和vue3中配置echarts的多图表同步缩放
背景:
解决echarts的多图表x轴同步联动的问题

⭐使用dataZoom api实现echart的同步缩放

echarts的datazoom api对外暴露
echarts-datazoom

原理:
echarts的实例存在datazoom缩放的方法,
所以只需要在datazoom事件触发其他图表的datazoom即可实现同步缩放

dispatchAction({
    type: 'dataZoom',
    // 可选,dataZoom 组件的 index,多个 dataZoom 组件时有用,默认为 0
    dataZoomIndex: number,
    // 开始位置的百分比,0 - 100
    start: number,
    // 结束位置的百分比,0 - 100
    end: number,
    // 开始位置的数值
    startValue: number,
    // 结束位置的数值
    endValue: number
})

注意:
x轴的范围要一致,不然可能会出现偏移

💖 vue2实现echarts多图表同步缩放

用变量记录echarts的实例,渲染完毕再触发datazoom

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>echarts 滚动事件</title>
		<!-- vue2 生产环境版本,优化了尺寸和速度 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
		<script src="./echarts.js"></script>
	</head>
	<style>
		#app {
			position: absolute;
			height: 100vh;
			width: 100vw;
		}
	</style>
	<body>
		<div id="app">
			<div>
				first
				<div id="first" style="width: 900px;height:400px;"></div>
				second
				<div id="second" style="width: 900px;height:400px;"></div>

				third
				<div id="third" style="width: 900px;height:400px;"></div>
			</div>
		</div>

		<script type="text/javascript">
			const instanceVue = {
				el: '#app',
				name: 'ecahrts',
				data() {
					return {
						firstChart: null,
						secondChart: null,
						thirdChart: null,
						maxNum:1000,
					};
				},
				mounted() {
					
					this.initSecondData()
					this.initThirdData()
					this.initFirstData()
				},
				methods: {
					initFirstData() {

						// 基于准备好的dom,初始化echarts实例
						var myChart = echarts.init(document.getElementById('first'));

						// 指定图表的配置项和数据
						let base = +new Date(1968, 9, 3);
						let oneDay = 24 * 3600 * 500;
						let date = [];
						let data = [Math.random() * 300];
						for (let i = 1; i < this.maxNum; i++) {
							var now = new Date((base += oneDay));
							date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
							data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
						}
						const option = {
							tooltip: {
								trigger: 'axis',
								position: function(pt) {
									return [pt[0], '10%'];
								}
							},
							title: {
								left: 'center',
								text: 'Large Area Chart'
							},
							toolbox: {
								feature: {
									dataZoom: {
										yAxisIndex: 'none'
									},
									restore: {},
									saveAsImage: {}
								}
							},
							xAxis: {
								type: 'category',
								boundaryGap: false,
								data: date
							},
							yAxis: {
								type: 'value',
								boundaryGap: [0, '100%']
							},
							dataZoom: [{
									type: 'inside',
									start: 0,
									end: 10
								},
								{
									start: 0,
									end: 10
								}
							],
							series: [{
								name: 'Fake Data',
								type: 'bar',
								symbol: 'none',
								sampling: 'lttb',
								itemStyle: {
									color: 'rgb(255, 70, 131)'
								},
								areaStyle: {
									color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
											offset: 0,
											color: 'rgb(255, 158, 68)'
										},
										{
											offset: 1,
											color: 'rgb(255, 70, 131)'
										}
									])
								},
								data: data
							}]
						};
						// 使用刚指定的配置项和数据显示图表。
						myChart.setOption(option);
						// 监听
						this.firstChart = myChart;
						this.asyncZoom()
					},
					asyncZoom() {
						const that = this
						this.firstChart.on('datazoom', function(params) {
							[that.secondChart, that.thirdChart].forEach(item => {
								console.log('item',item)
								item && item.dispatchAction({ // 触发 dataZoom 事件
									type: 'dataZoom',
									zoomLock: true, // 锁定整个图表的缩放功能
									xAxisIndex: params
										.xAxisIndex, // xAxisIndex 为当前操作的 xAxisIndex,用于确定对应的 xAxis 对象
									yAxisIndex: params
										.yAxisIndex, // yAxisIndex 为当前操作的 yAxisIndex,用于确定对应的 yAxis 对象
									start: params.start, // start 为当前操作的时间范围起始值
									end: params.end // end 为当前操作的时间范围结束值
								});
							})
						})
					},
					initSecondData() {
						// 基于准备好的dom,初始化echarts实例
						const myChart = echarts.init(document.getElementById('second'));
						// 指定图表的配置项和数据
						let base = +new Date(1968, 9, 3);
						let oneDay = 24 * 3600 * 500;
						const date = []
						const yData1 = [Math.random() * 300]
						const yData2 = [Math.random() * 100]
						for (let i = 1; i < this.maxNum; i++) {
							var now = new Date((base += oneDay));
							date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'))
							yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));
							yData2.push(Math.round((Math.random() - 0.5) * 20 + yData2[i - 1]));
						}
						const option = {
							title: {
								text: 'line'
							},
							tooltip: {
								trigger: 'axis'
							},
							legend: {},
							toolbox: {
								show: true,
								feature: {
									dataZoom: {
										yAxisIndex: 'none'
									},
									dataView: {
										readOnly: false
									},
									magicType: {
										type: ['line', 'bar']
									},
									restore: {},
									saveAsImage: {}
								}
							},
							xAxis: {
								type: 'category',
								boundaryGap: false,
								data: date
							},
							yAxis: {
								type: 'value',
								axisLabel: {
									formatter: '{value} °C'
								}
							},
							series: [{
									name: 'Highest',
									type: 'line',
									data: yData1,
									markPoint: {
										data: [{
												type: 'max',
												name: 'Max'
											},
											{
												type: 'min',
												name: 'Min'
											}
										]
									},
									markLine: {
										data: [{
											type: 'average',
											name: 'Avg'
										}]
									}
								},
								{
									name: 'Lowest',
									type: 'line',
									data: yData2,
									markPoint: {
										data: [{
											name: '周最低',
											value: -2,
											xAxis: 1,
											yAxis: -1.5
										}]
									},
									markLine: {
										data: [{
												type: 'average',
												name: 'Avg'
											},
											[{
													symbol: 'none',
													x: '90%',
													yAxis: 'max'
												},
												{
													symbol: 'circle',
													label: {
														position: 'start',
														formatter: 'Max'
													},
													type: 'max',
													name: '最高点'
												}
											]
										]
									}
								}
							]
						};
						myChart.setOption(option);
						this.secondChart = myChart;
					},
					initThirdData() {
						// 基于准备好的dom,初始化echarts实例
						const myChart = echarts.init(document.getElementById('third'));
						// 指定图表的配置项和数据
						let base = +new Date(1968, 9, 3);
						let oneDay = 24 * 3600 * 500;
						const date = []
						const yData1 = [Math.random() * 300]
						for (let i = 1; i < this.maxNum; i++) {
							var now = new Date((base += oneDay));
							date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'))
							yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));
						}
						option = {
							toolbox: {
								show: true,
								feature: {
									dataZoom: {
										yAxisIndex: 'none'
									},
									dataView: {
										readOnly: false
									},
									magicType: {
										type: ['line', 'bar']
									},
									restore: {},
									saveAsImage: {}
								}
							},
							tooltip:{
								trigger:'axis'
							},
							legend: {},
							grid: {
								left: '3%',
								right: '4%',
								bottom: '3%',
								containLabel: true
							},
							xAxis: [{
								type: 'category',
								boundaryGap: false,
								data: date
							}],
							yAxis: [{
								type: 'value',
							}],
							series: [{
									name: 'Direct',
									type: 'bar',
									data: yData1
								}
							]
						};
						myChart.setOption(option);
						this.thirdChart = myChart;
					}
				}
			}
			// 实例化
			new Vue(instanceVue);
		</script>
	</body>
</html>

代码在insidecode,如下运行即可


效果:
vue2-datazoom-chart

💖 vue3实现echarts多图表同步缩放

用state存储echarts实例,渲染完之后触发dataZoom

<template>
  <div>
    <!--    折线图-->
    <div id="first" :style="{ width, height }"></div>
    <!--    柱状图-->
    <div id="second" :style="{ width, height }"></div>
    <div id="third" :style="{ width, height }"></div>
    <div id="fourth" :style="{ width, height }"></div>
  </div>
</template>
<script lang="ts" setup>
  import {  reactive, onMounted } from 'vue';
  import * as echarts from 'echarts';

  const state: any = reactive({
    maxNum: 100,
    // 折线图
    lineChart1: null,
    // 柱状图1
    barChart1: null,
    // 柱状图2
    barChart2: null,
    // 柱状图3
    barChart3: null,
  });

  function asyncZoom() {
    console.log(' state.lineChart1', state.lineChart1);
    state?.lineChart1?.on('datazoom', function (params) {
      [state.barChart1, state.barChart2, state.barChart2, state.barChart3].forEach((item) => {
        console.log('item', item);
        item &&
          item.dispatchAction({
            // 触发 dataZoom 事件
            type: 'dataZoom',
            zoomLock: true, // 锁定整个图表的缩放功能
            xAxisIndex: params.xAxisIndex, // xAxisIndex 为当前操作的 xAxisIndex,用于确定对应的 xAxis 对象
            yAxisIndex: params.yAxisIndex, // yAxisIndex 为当前操作的 yAxisIndex,用于确定对应的 yAxis 对象
            start: params.start, // start 为当前操作的时间范围起始值
            end: params.end, // end 为当前操作的时间范围结束值
          });
      });
    });
  }

  function renderLineChart4(val: any): any {
    // const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);
    const myChart = echarts.init(document.getElementById('fourth'));
    if (!myChart) {
      return;
    }
    // 指定图表的配置项和数据
    let base = +new Date(1968, 9, 3);
    let oneDay = 24 * 3600 * 500;
    const date = [];
    const yData1 = [Math.random() * 300];
    for (let i = 1; i < state.maxNum; i++) {
      var now = new Date((base += oneDay));
      date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
      yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));
    }
    const option = {
      toolbox: {
        show: true,
        feature: {
          dataZoom: {
            yAxisIndex: 'none',
          },
          dataView: {
            readOnly: false,
          },
          magicType: {
            type: ['line', 'bar'],
          },
          restore: {},
          saveAsImage: {},
        },
      },
      legend: {},
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          boundaryGap: false,
          data: date,
        },
      ],
      yAxis: [
        {
          type: 'value',
        },
      ],
      series: [
        {
          name: 'Direct',
          type: 'bar',
          data: yData1,
        },
      ],
    };
    console.log('option', option);
    myChart.setOption(option, true);
    // dom.setOption(option, true);
    state.barChart3 = myChart;
  }

  function renderLineChart3(val: any): any {
    // const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);
    const myChart = echarts.init(document.getElementById('third'));
    if (!myChart) {
      return;
    }
    // 指定图表的配置项和数据
    let base = +new Date(1968, 9, 3);
    let oneDay = 24 * 3600 * 500;
    const date = [];
    const yData1 = [Math.random() * 300];
    for (let i = 1; i < state.maxNum; i++) {
      var now = new Date((base += oneDay));
      date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
      yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));
    }
    const option = {
      toolbox: {
        show: true,
        feature: {
          dataZoom: {
            yAxisIndex: 'none',
          },
          dataView: {
            readOnly: false,
          },
          magicType: {
            type: ['line', 'bar'],
          },
          restore: {},
          saveAsImage: {},
        },
      },
      legend: {},
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          boundaryGap: false,
          data: date,
        },
      ],
      yAxis: [
        {
          type: 'value',
        },
      ],
      series: [
        {
          name: 'Direct',
          type: 'bar',
          data: yData1,
        },
      ],
    };
    console.log('option', option);
    myChart.setOption(option, true);
    // dom.setOption(option, true);
    state.barChart2 = myChart;
  }

  function renderLineChart2(val: any): any {
    // const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);
    const myChart = echarts.init(document.getElementById('second'));
    if (!myChart) {
      return;
    }
    let base = +new Date(1968, 9, 3);
    let oneDay = 24 * 3600 * 500;
    const date = [];
    const yData1 = [Math.random() * 300];
    const yData2 = [Math.random() * 100];
    for (let i = 1; i < state.maxNum; i++) {
      var now = new Date((base += oneDay));
      date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
      yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));
      yData2.push(Math.round((Math.random() - 0.5) * 20 + yData2[i - 1]));
    }
    const option = {
      title: {
        text: 'line',
      },
      tooltip: {
        trigger: 'axis',
      },
      legend: {},
      toolbox: {
        show: true,
        feature: {
          dataZoom: {
            yAxisIndex: 'none',
          },
          dataView: {
            readOnly: false,
          },
          magicType: {
            type: ['line', 'bar'],
          },
          restore: {},
          saveAsImage: {},
        },
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: date,
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          formatter: '{value} °C',
        },
      },
      series: [
        {
          name: 'Highest',
          type: 'line',
          data: yData1,
          markPoint: {
            data: [
              {
                type: 'max',
                name: 'Max',
              },
              {
                type: 'min',
                name: 'Min',
              },
            ],
          },
          markLine: {
            data: [
              {
                type: 'average',
                name: 'Avg',
              },
            ],
          },
        },
        {
          name: 'Lowest',
          type: 'line',
          data: yData2,
          markPoint: {
            data: [
              {
                name: '周最低',
                value: -2,
                xAxis: 1,
                yAxis: -1.5,
              },
            ],
          },
          markLine: {
            data: [
              {
                type: 'average',
                name: 'Avg',
              },
              [
                {
                  symbol: 'none',
                  x: '90%',
                  yAxis: 'max',
                },
                {
                  symbol: 'circle',
                  label: {
                    position: 'start',
                    formatter: 'Max',
                  },
                  type: 'max',
                  name: '最高点',
                },
              ],
            ],
          },
        },
      ],
    };
    console.log('option', option);
    myChart.setOption(option, true);
    // dom.setOption(option, true);
    state.barChart1 = myChart;
  }

  function renderLineChart1(val: any): any {
    // const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);
    const myChart = echarts.init(document.getElementById('first'));
    if (!myChart) {
      return;
    }
    // 指定图表的配置项和数据
    let base = +new Date(1968, 9, 3);
    let oneDay = 24 * 3600 * 500;
    let date = [];
    let data = [Math.random() * 300];
    for (let i = 1; i < state.maxNum; i++) {
      var now = new Date((base += oneDay));
      date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
      data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
    }
    const option = {
      tooltip: {
        trigger: 'axis',
        position: function (pt) {
          return [pt[0], '10%'];
        },
      },
      title: {
        left: 'center',
        text: 'Large Area Chart',
      },
      toolbox: {
        feature: {
          dataZoom: {
            yAxisIndex: 'none',
          },
          restore: {},
          saveAsImage: {},
        },
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: date,
      },
      yAxis: {
        type: 'value',
        boundaryGap: [0, '100%'],
      },
      dataZoom: [
        {
          type: 'inside',
          start: 0,
          end: 10,
        },
        {
          start: 0,
          end: 10,
        },
      ],
      series: [
        {
          name: 'Fake Data',
          type: 'bar',
          symbol: 'none',
          sampling: 'lttb',
          itemStyle: {
            color: 'rgb(255, 70, 131)',
          },
          data: data,
        },
      ],
    };
    console.log('option', option);
    myChart.setOption(option, true);
    state.lineChart1 = myChart;
    asyncZoom();
  }
  onMounted(() => {
    renderLineChart4();
    renderLineChart3();
    renderLineChart2();
    renderLineChart1();
  });
</script>

效果
vue3-dataZoom

⭐结束

本文分享结束, 💖 感谢你的阅读💖
如有不足或者错误欢迎指出!
scene-line-sky

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

教你如何使用Nodejs搭建HTTP web服务器并发布上线公网

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 转载自内网穿透工具的文章&#xff1a;使用Nodejs搭建HTTP服务&#xff0c;并实现公网远程访问「内网穿透」 前言 Node.js…

自动驾驶开源数据集(附下载链接)

自动驾驶是带动新兴产业的一个突破点&#xff0c;也是中国结合新能源汽车&#xff0c;实现汽车产业弯道超车的不二手段&#xff0c;是打破国外燃油车技术壁垒的关键一步&#xff01;它不会停止&#xff0c;只是在蓄势待发&#xff01; 数据集介绍&#xff1a;点击 自动驾驶场…

使用MATLAB画SCI论文图

从gcf和gca说起 不论是 Python 绘图还是Matlab绘图&#xff0c;想要获得更好看的图&#xff0c;都会用到这两个单词。 gcf&#xff1a;get current figure&#xff0c;是目标图像的图形句柄对象 gca&#xff1a;get current axes&#xff0c;是目标图像的坐标轴句柄对象 Mat…

java 全局、局部异常处理详解及result结果封装

1、引入spring-boot-starter-web依赖和new-swagger依赖 <dependency><groupId>com.jjw</groupId><artifactId>new-swagger</artifactId><version>1.0-SNAPSHOT</version> </dependency> <dependency><groupId>or…

【Vue2】Vant2上传文件使用formData方式,base64图片转Blob再转File上传

文章目录 前言一、base64转换为 Blob 对象的方法二、使用步骤1.引入工具类js2.编写formData上传方法3.api方法中的request代码 三、实际操作1.html代码2.js代码 总结 前言 vant2上传组件传送门 使用vant2组件中的uploader组件 <van-uploader v-model"fileList" …

耳挂式骨传导耳机哪个牌子好,分享几个品牌的骨传导耳机

骨传导耳机就是利用震动来传递声音的耳机&#xff0c;在运动时佩戴骨传导耳机&#xff0c;可以听歌也能听周围的声音&#xff0c;提高了运动时的安全性。目前市面上的骨传导耳机也是琳琅满目。今天就来给大家分享下目前市面上比较常见的几款骨传导耳机。希望对正在选购骨传导耳…

什么是kafka,如何学习kafka,整合SpringBoot

目录 一、什么是Kafka&#xff0c;如何学习 二、如何整合SpringBoot 三、Kafka的优势 一、什么是Kafka&#xff0c;如何学习 Kafka是一种分布式的消息队列系统&#xff0c;它可以用于处理大量实时数据流。学习Kafka需要掌握如何安装、配置和运行Kafka集群&#xff0c;以及如…

代码随想录算法训练营第五十三天|1143.最长公共子序列、1035.不相交的线、53. 最大子序和 动态规划

最长公共子序列 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 和上一题一样&#xff0c;dp[i][j]代表&#xff1a; 长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]确定递推公式 主要就是两大情况&#xff1a; text1[…

一步一步学OAK之三:实现RGB相机场景切换

目录 Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 遍历所有场景模式和特效模式Setup 5: 创建pipelineSetup 6: 创建节点Setup 7: 连接设备并启动管道Setup 8: 创建与DepthAI设备通信的输入队列和输出队列Setup 9: 定义putText函数Setup 10: 主循环获取视…

uni-app

uni-app 一、准备工作1.新建项目2.配置浏览器3.兼容4.新建页面 二、上手1.pages.json文件的页面配置与全局配置2.rpx尺寸单位3.内置组件4.vue写法 一、准备工作 uni-app文档 HBuilderX&#xff0c;H是HTML的首字母&#xff0c;Builder是构造者&#xff0c;X是HBuilder的下一代版…

实例005 可以拉伸的菜单界面

实例说明 如果管理程序功能菜单非常多&#xff0c;而用户只使用一些常用菜单&#xff0c;这时&#xff0c;可以将主菜单项下的不常用菜单隐藏起来。此种显示方式类似于对菜单进行拉伸。使用时&#xff0c;只需单击展开菜单&#xff0c;即可显示相应菜单功能。运行本例&#xf…

使用Python批量进行数据分析

案例01 批量升序排序一个工作簿中的所有工作表——产品销售统计表.xlsx import xlwings as xw import pandas as pd app xw.App(visible False, add_book False) workbook app.books.open(产品销售统计表.xlsx) worksheet workbook.sheets # 列出工作簿中的所有工作表 fo…

VVIC搜款网API接口:获取商品详情数据API

VVIC电商平台汇集了数千家优质品牌和供应商&#xff0c;包括服装、家居用品、电子产品、美妆产品、食品和饮料等各种商品。消费者可以在VVIC上找到各类品牌和产品&#xff0c;满足他们的购物需求。VVIC还提供了多种付款方式和物流配送服务&#xff0c;确保消费者的购物过程顺利…

第27章 uView 内置路由使用注意事项

1 uView 内置路由不支持通过“localhost”域名直接获取数据。 在前后分离开发中“axios” 路由支持使用“localhost”域名或IP地址获取后端的数据&#xff0c;所以不管是IIS部署还是后端调试通过“axios” 路由都能获取数据&#xff0c;对于.NetCore的前后端分离开发来说“axio…

NLP学习笔记(二)

文章目录 &#xff08;一&#xff09;负采样&#xff08;二&#xff09;GloVe1.带全局语料库的跳元模型2.GloVe模型3.问题4.跳元模型与GloVe模型的比较 &#xff08;三&#xff09;问题1.参数初始化2.梯度下降3.下游任务4.句法信息5.似然估计6.词向量表示 &#xff08;一&#…

2023 中兴捧月算法挑战赛-自智网络-参赛总结

“中兴捧月”是由中兴通讯面向在校大学生举办的全球性系列赛事活动&#xff0c;致力于培养学生建模编程、创新、方案策划和团队合作能力。今年是在学校的宣传下了解到比赛&#xff0c;最初抱着学习的态度报名了比赛&#xff0c;最终进入了决赛&#xff0c;完成了封闭的开发与赛…

Jenkins+Gitlab+Springboot项目部署Jar和image两种方式

Springboot环境准备 利用spring官网快速创建springboot项目。 添加一个controller package com.example.demo;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController public class…

【结构型设计模式】桥接模式

一、写在前面 桥接模式&#xff08;Bridge&#xff09;&#xff1a;桥接模式是一种结构型设计模式&#xff0c;其目的是将抽象部分和实现部分分离&#xff0c;允许它们可以独立地变化。该模式通过创建一个桥接类&#xff0c;连接抽象和实现&#xff0c;使得它们可以独立地进行…

网络安全(黑客)自学笔记

建议一&#xff1a;黑客七个等级 黑客&#xff0c;对很多人来说充满诱惑力。很多人可以发现这门领域如同任何一门领域&#xff0c;越深入越敬畏&#xff0c;知识如海洋&#xff0c;黑客也存在一些等级&#xff0c;参考知道创宇 CEO ic&#xff08;世界顶级黑客团队 0x557 成员…

C语言:数据的存储

往期文章 C语言&#xff1a;初识C语言C语言&#xff1a;分支语句和循环语句C语言&#xff1a;函数C语言&#xff1a;数组C语言&#xff1a;操作符详解C语言&#xff1a;指针详解C语言&#xff1a;结构体 目录 往期文章前言1. 数据的类型2. 整型在内存中的存储2.1 原码、反码、…