uni-app APP端canvas使用总结_uniapp canvas-程序员宅基地

技术标签: android  ios  uni-app  

场景:大概21年4月份的时候,项目预规划了“自定义流程图需求”,并且能够根据后端返回数据,实现动态流程图(节点状态、流程线状态、节点数量等动态变化)。当时项目正有2-3天的空档期,于是就利用这几天,熟悉了一下uni-app中canvas api,基于设计稿,先行绘制出了静态图。并且,基于movable-area和movable-view组件,对流程图添加了手势缩放与拖拽功能。不过到目前,该需求也没有在项目中实际落实。本文将将基于该静态流程图,对uni-app中canvas基本使用做一个介绍。

官网API文档:Canvas API

Canvas组件文档:Canvas

设计图原图展示:

开发:

        ①:首先是视图层代码,主要的是Canvas的一些配置,其中canvas-id必须配置,且要唯一;并且如果不设置宽高,默认宽高是300px与225px,我这边是根据设计图大小设置的。此外,Canvas开发最佳、最简便的是在vue页面开发,nvue页面需要兼容,并且性能可能不佳。具体见官网Canvas组件介绍。

<template>
	<view>
		<scroll-view :scroll-x="true" :scroll-left="srcollTo" :scroll-with-animation="true">
			<movable-area :scale-area="true" style="width: 750rpx;height: 1257px;">
				<movable-view direction="all" :scale-min="0.5" :scale-max="1"  :scale="true"
					 @scale="scaleChange" :disabled="true">
					 <!--这边关闭了拖拽-->
					<!-- <scroll-view :scroll-x="true" :scroll-left="srcollTo" :scroll-with-animation="true"> -->
					<canvas id="myCanvas" canvas-id="myCanvas" style="width: 1200px;height: 1257px;"
						@touchstart="touchstart" />
						<!-- </scroll-view> -->
				</movable-view>
			</movable-area>
		</scroll-view>
	</view>
</template>

       

         ②:注意事项:

        1. 绘制顺序要注意,比如我画一个流程节点,要先画背景,然后画字,否则字会被遮挡。

        2. Canvas的draw()方法只需在所有元素绘制完成后调用一次就行。

        3.其余还没想到。

        ③:下面介绍一下关键的绘制函:

        1. drawImage:图片绘制,入参:Canvas 上下文、x、y、宽、高;

drawImage(ctx, path, x, y, dWidth, dHeight) {
				ctx.drawImage(path, x, y, dWidth, dHeight)
			},

        2. roundNode:圆角矩形节点绘制,入参:Canvas 上下文、x、y、宽、高、弧度、填充色值;主要原理是通过arcTo方法绘制圆弧,最后填充颜色;

//圆角矩形
			roundNode(ctx, x, y, width, height, radius, color) {
				ctx.beginPath()
				if (width < 2 * radius) radius = width / 2;
				if (height < 2 * radius) radius = height / 2;
				ctx.moveTo(x + radius, y);
				ctx.arcTo(x + width, y, x + width, y + height, radius);
				ctx.arcTo(x + width, y + height, x, y + height, radius);
				ctx.arcTo(x, y + height, x, y, radius);
				ctx.arcTo(x, y, x + width, y, radius);
				ctx.setFillStyle(color)
				ctx.fill()
			},

        3. diamondNode:菱形节点绘制,入参:Canvas 上下文、x、y、宽、高、线宽、填充色值;菱形节点绘制是基于圆角节点进行的,arcTo方法相当于一阶贝塞尔曲线,通过控制控制点的位置实现圆弧位置变动。但这个方法绘制出来有个缺口,存在一点瑕疵,后续项目正式将该需求提上计划后再优化

//菱形绘制
			diamondNode(ctx, x, y, width, height, lineColor, bgColor) {
				ctx.beginPath()
				ctx.setLineDash([])
				ctx.setLineWidth(4)

				ctx.moveTo(x + 20, y + 20);
				ctx.arcTo(x + width / 2, y, x + width, y + height / 2, 5);
				ctx.arcTo(x + width, y + height / 2, x + width / 2, y + height, 8);
				ctx.arcTo(x + width / 2, y + height, x, y + height / 2, 5);
				ctx.arcTo(x, y + height / 2, x + width / 2, y, 8);

				ctx.setStrokeStyle(lineColor)
				ctx.stroke()
				ctx.setFillStyle(bgColor)
				ctx.fill()
			},

        4. drawTriangle:三角形绘制,该方法与线段绘制组合使用,入参:Canvas 上下文、x、y、填充色、箭头方向;这边为了方便起见,箭头大小是写死的,我这边的箭头绘制原理是:基于指定点,绘制线段填充实现。

//绘制三角形  type:箭头朝向:bottom、right、left
			drawTriangle(ctx, x, y, color, type) {
				ctx.beginPath()
				let height = 10 //计算等边三角形的高
				ctx.moveTo(x, y); //x y开始

				switch (type) {
					case 'bottom':
						ctx.lineTo(x - height / 2, y)
						ctx.lineTo(x, y + height)
						ctx.moveTo(x, y)
						ctx.lineTo(x + height / 2, y)
						ctx.lineTo(x, y + height)
						break;
					case 'left':
						ctx.lineTo(x, y - height / 2)
						ctx.lineTo(x - height, y)
						ctx.moveTo(x, y)
						ctx.lineTo(x, y + height / 2)
						ctx.lineTo(x - height, y)
						break;
					case 'right':
						ctx.lineTo(x, y - height / 2)
						ctx.lineTo(x + height, y)
						ctx.moveTo(x, y)
						ctx.lineTo(x, y + height / 2)
						ctx.lineTo(x + height, y)
						break;
					default:
						break;
				}
				ctx.setFillStyle(color) //以纯色绿色填充
				ctx.fill();
			}

        5. drawText:文字绘制,入参:Canvas 上下文、x、y、填充色、文字大小;这边文字绘制在水平方向,通过measureText计算文字宽度,进行了适配;而文字竖直方向适配,试了几种网上的方法,一直没有成功,暂时做了统一偏移量处理。

drawText(ctx, text, x, y, color, size) {
				//文字部分
				ctx.beginPath()
				ctx.setTextAlign('center')
				ctx.setFillStyle(color)
				ctx.setFontSize(size)
				const metrics = ctx.measureText(text)
				console.log(metrics.width)
				//文字统一偏移
				ctx.fillText(text, x + metrics.width / 2, y + 17)
			},

        6. drawLine: 绘制线段,入参:Canvas 上下文、起始点x、起始点y、目标点x、目标点y、填充色、文字大小、箭头朝向、是否带箭头、是否虚线;线段绘制方法比较简单。

drawLine(ctx, fromX, fromY, toX, toY, color, type, isArrow = true, isDash = false) {
				ctx.beginPath()
				if (isDash) {
					ctx.setLineDash([10]);
				} else {
					ctx.setLineDash([]);
				}
				ctx.moveTo(fromX, fromY)
				ctx.lineTo(toX, toY)
				ctx.setLineWidth(1)
				ctx.setStrokeStyle(color)
				ctx.stroke()
				
				//是否绘制箭头
				if (isArrow) {
					this.drawTriangle(ctx, toX, toY, color, type)
				}
			},

        7. touchstart:Canvas触摸事件监听,用于实现流程图中节点的点击。实际使用需要记录每个节点的x、y坐标点、宽、高,通过这些参数对点击区域进行计算与判断,并且还要考虑缩放而带来的坐标点变化。

touchstart(e) {
				//点击事件有点复杂,要根据点击点、绘制位置、缩放比例判断点击了哪个节点,
				let x = e.touches[0].x
				let y = e.touches[0].y
				this.node.forEach(item => {
					// console.log("item.x * this.scale:"+item.x * this.scale)
					// console.log("item.y * this.scale:"+item.y * this.scale)
					if (x > item.x * this.scale && x < (item.x + item.w) * this.scale
						&& y > item.y * this.scale && y < (item.y + item.h) * this.scale) {
						//在范围内,根据标记定义节点类型
						console.log(item.targe)
						uni.showToast({
							icon:'none',
							title:item.name
						})
					}
				}) 
				console.log("x:"+x + "    y:"+y)
			},

         ④:逻辑层代码量比较多,略微复杂,这边全部贴出来,供参考。部分静态图片资源就不提供了,运行的时候替换一下或注释掉都行。       

<script>
	export default {
		data() {
			return {
				context: null,
				srcollTo: 0,
				scale: 1, //缩放比例
				node:[],//节点坐标与长宽
			}
		},
		onLoad(e) {
			//上个页面传递的数据
		},
		onReady() {
			this.srcollTo = 0
			this.$nextTick(() => {
				this.srcollTo = 435
			})
			this.context = uni.createCanvasContext('myCanvas')

			//画背景
			this.drawImage(this.context, '/static/bg.png', 0, 0, 1200, 1257)

			//画节点
			//开始节点
			this.roundNode(this.context, 553, 38, 100, 36, 26, '#1EC1C3')
			this.node.push({
				x:553,
				y:38,
				w:100,
				h:36,
				targe:0
			})
			//检修发起抄送 
			this.roundNode(this.context, 755, 89, 157, 36, 26, '#1EC1C3')
			//检修前准备
			this.roundNode(this.context, 525, 265, 164, 36, 2, '#1EC1C3')
			//车间主任审核
			this.roundDashNode(this.context, 525, 360, 156, 36, 2)
			//质量大班长
			this.roundDashNode(this.context, 743, 265, 188, 36, 2)
			//是否停电
			this.diamondNode(this.context, 308, 120, 108, 62, '#00A1FF', '#FFFFFF')
			//停电确认
			this.roundNode(this.context, 52, 214, 120, 36, 26, '#B9C2D6')
			//停电抄送
			this.roundNode(this.context, 298, 265, 128, 36, 2, '#B9C2D6')
			//风险等级
			this.diamondNode(this.context, 549, 441, 108, 62, '#B9C2D6', '#EEF1F7')
			//安全审核
			this.roundNode(this.context, 531, 546, 148, 36, 2, '#B9C2D6')
			//审批
			this.roundNode(this.context, 531, 645, 148, 36, 2, '#B9C2D6')
			//检修中
			this.roundNode(this.context, 531, 744, 148, 36, 2, '#B9C2D6')
			//需要送电
			this.diamondNode(this.context, 549, 861, 108, 62, '#B9C2D6', '#EEF1F7')
			//完成检修抄送
			this.roundNode(this.context, 278, 804, 167, 36, 26, '#B9C2D6')
			//送电
			this.roundNode(this.context, 772, 876, 118, 36, 2, '#B9C2D6')
			//送电抄送
			this.roundNode(this.context, 1020, 876, 113, 36, 26, '#B9C2D6')
			//维修验收
			this.roundNode(this.context, 529, 1009, 148, 36, 2, '#B9C2D6')
			//结束节点
			this.roundNode(this.context, 553, 1101, 100, 36, 26, '#B9C2D6')
			
			

			//画线
			//开始 to  检修发起抄送
			this.drawLine(this.context, 602, 75, 602, 247, '#1EC1C3', 'bottom')
			//to  检修前准备
			this.drawLine(this.context, 602, 107, 747, 107, '#1EC1C3', 'right')
			//to 车间主任审批
			this.drawLine(this.context, 602, 306, 602, 346, '#00A1FF', 'bottom', true, true)
			//to 质量安全大班长
			this.drawLine(this.context, 411, 152, 837, 152, '#00A1FF', '', false, true)
			this.drawLine(this.context, 837, 153, 837, 255, '#00A1FF', 'bottom', true, true)

			//to 停电确认
			this.drawLine(this.context, 362, 182, 362, 252, '#AFB9C5', 'bottom', true, true)
			//to 停电抄送
			this.drawLine(this.context, 361, 231, 184, 231, '#AFB9C5', 'left', true, true)
			//to 风险等级
			this.drawLine(this.context, 602, 403, 602, 430, '#AFB9C5', 'bottom', true, true)
			//to 安全审核
			this.drawLine(this.context, 602, 506, 602, 536, '#AFB9C5', 'bottom', true, true)
			//to 审批
			this.drawLine(this.context, 602, 589, 602, 629, '#AFB9C5', 'bottom', true, true)
			//to 检修中
			this.drawLine(this.context, 602, 692, 602, 732, '#AFB9C5', 'bottom', true, true)
			//to 需要送电
			this.drawLine(this.context, 602, 790, 602, 850, '#AFB9C5', 'bottom', true, true)
			//to 完成检修抄送
			this.drawLine(this.context, 603, 821, 455, 821, '#AFB9C5', 'left', true, true)
			//to 送电
			this.drawLine(this.context, 656, 892, 756, 892, '#AFB9C5', 'right', true, true)
			//to 送电抄送
			this.drawLine(this.context, 900, 892, 1010, 892, '#AFB9C5', 'right', true, true)
			// 送电 to 维修验收
			this.drawLine(this.context, 835, 921, 835, 966, '#AFB9C5', '', false, true)
			this.drawLine(this.context, 602, 966, 835, 966, '#AFB9C5', '', false, true)
			
			//to 维修验收
			this.drawLine(this.context, 602, 931, 602, 1000, '#AFB9C5', 'bottom', true, true)
			//to 结束
			this.drawLine(this.context, 602, 1054, 602, 1090, '#AFB9C5', 'bottom', true, true)

			//画文字、图标
			this.drawText(this.context, '开始', 587, 45, '#FFFFFF', 18)

			this.drawText(this.context, '检修发起抄送', 783, 96, '#FFFFFF', 16)
			this.drawIcon('complete', 883, 97)

			this.drawText(this.context, '检修前准备', 553, 272, '#FFFFFF', 16)
			this.drawIcon('complete', 637, 274)

			this.drawText(this.context, '车间主任审核', 552, 367, '#00A1FF', 16)
			this.drawIcon('loading', 653, 368)
			this.drawIcon('me', 530, 358)

			this.drawText(this.context, '质量安全大班长监督', 754, 272, '#00A1FF', 16)
			this.drawIcon('loading', 904, 274)

			this.drawText(this.context, '需要停电', 328, 140, '#333333', 16)
			this.drawText(this.context, '是', 367, 193, '#FFAD10', 16)

			this.drawText(this.context, '停电确认', 330, 272, '#FFFFFF', 16)
			this.drawIcon('unstart', 397, 273)
			this.drawIcon('me', 304, 263)

			this.drawText(this.context, '停电抄送', 67, 220, '#FFFFFF', 16)
			this.drawIcon('unstart', 140, 221)
			
			this.drawText(this.context, '中危', 587, 461, '#8695AE', 16)
			
			this.drawText(this.context, '安全审核', 558, 553, '#FFFFFF', 16)
			this.drawIcon('unstart', 636, 554)
			
			this.drawText(this.context, '审批(中危)', 558, 652, '#FFFFFF', 16)
			this.drawIcon('unstart', 636, 653)
			
			this.drawText(this.context, '检修中', 558, 751, '#FFFFFF', 16)
			this.drawIcon('unstart', 636, 752)
			
			this.drawText(this.context, '需要送电', 571, 880, '#8695AE', 16)
			this.drawText(this.context, '是', 694, 863, '#FFAD10', 16)
			this.drawText(this.context, '否', 580, 951, '#FFAD10', 16)
			
			this.drawText(this.context, '完成检修抄送', 302, 811, '#FFFFFF', 16)
			this.drawIcon('unstart', 402, 813)
			
			this.drawText(this.context, '送电', 803, 883, '#FFFFFF', 16)
			this.drawIcon('unstart', 839, 884)
			
			this.drawText(this.context, '送电抄送', 1033, 883, '#FFFFFF', 16)
			this.drawIcon('unstart', 1099, 884)
			
			this.drawText(this.context, '维修验收', 560, 1016, '#FFFFFF', 16)
			this.drawIcon('unstart', 627, 1017)
			
			this.drawText(this.context, '结束', 587, 1108, '#FFFFFF', 18)

			//画
			this.context.draw()
		},
		methods: {
			drawImage(ctx, path, x, y, dWidth, dHeight) {
				ctx.drawImage(path, x, y, dWidth, dHeight)
			},

			//type loading, unstart, complete, me
			drawIcon(type, x, y) {
				switch (type) {
					case 'loading':
						this.drawImage(this.context, '/static/loading.png', x, y, 20, 20)
						break;
					case 'unstart':
						this.drawImage(this.context, '/static/unstart.png', x, y, 20, 20)
						break;
					case 'complete':
						this.drawImage(this.context, '/static/finish.png', x, y, 20, 20)
						break;
					case 'me':
						this.drawImage(this.context, '/static/me.png', x, y, 18, 23)
						break;
					default:
						break;
				}
			},

			//圆角矩形
			roundNode(ctx, x, y, width, height, radius, color) {

				//圆角矩形部分
				ctx.beginPath()
				if (width < 2 * radius) radius = width / 2;
				if (height < 2 * radius) radius = height / 2;
				ctx.moveTo(x + radius, y);
				ctx.arcTo(x + width, y, x + width, y + height, radius);
				ctx.arcTo(x + width, y + height, x, y + height, radius);
				ctx.arcTo(x, y + height, x, y, radius);
				ctx.arcTo(x, y, x + width, y, radius);
				ctx.setFillStyle(color)
				ctx.fill()
			},
			//虚线圆角矩形 样式固定
			roundDashNode(ctx, x, y, width, height, radius) {
				ctx.beginPath()
				if (width < 2 * radius) radius = width / 2;
				if (height < 2 * radius) radius = height / 2;
				ctx.setLineDash([10])
				ctx.setLineWidth(2)


				ctx.moveTo(x + radius, y);
				ctx.arcTo(x + width, y, x + width, y + height, radius);
				ctx.arcTo(x + width, y + height, x, y + height, radius);
				ctx.arcTo(x, y + height, x, y, radius);
				ctx.arcTo(x, y, x + width, y, radius);

				ctx.setStrokeStyle('#00A1FF')
				ctx.stroke()
				ctx.setFillStyle('#D5EAFE')
				ctx.fill()
			},
			//菱形绘制
			diamondNode(ctx, x, y, width, height, lineColor, bgColor) {
				ctx.beginPath()
				ctx.setLineDash([])
				ctx.setLineWidth(4)

				ctx.moveTo(x + 20, y + 20);
				ctx.arcTo(x + width / 2, y, x + width, y + height / 2, 5);
				ctx.arcTo(x + width, y + height / 2, x + width / 2, y + height, 8);
				ctx.arcTo(x + width / 2, y + height, x, y + height / 2, 5);
				ctx.arcTo(x, y + height / 2, x + width / 2, y, 8);

				ctx.setStrokeStyle(lineColor)
				ctx.stroke()
				ctx.setFillStyle(bgColor)
				ctx.fill()
			},

			//绘制三角形  type:箭头朝向:bottom、right、left
			drawTriangle(ctx, x, y, color, type) {
				ctx.beginPath()
				let height = 10 //计算等边三角形的高
				ctx.moveTo(x, y); //x y开始

				switch (type) {
					case 'bottom':
						ctx.lineTo(x - height / 2, y)
						ctx.lineTo(x, y + height)
						ctx.moveTo(x, y)
						ctx.lineTo(x + height / 2, y)
						ctx.lineTo(x, y + height)
						break;
					case 'left':
						ctx.lineTo(x, y - height / 2)
						ctx.lineTo(x - height, y)
						ctx.moveTo(x, y)
						ctx.lineTo(x, y + height / 2)
						ctx.lineTo(x - height, y)
						break;
					case 'right':
						ctx.lineTo(x, y - height / 2)
						ctx.lineTo(x + height, y)
						ctx.moveTo(x, y)
						ctx.lineTo(x, y + height / 2)
						ctx.lineTo(x + height, y)
						break;
					default:
						break;
				}


				ctx.setFillStyle(color) //以纯色绿色填充
				ctx.fill();
			},

			drawText(ctx, text, x, y, color, size) {
				//文字部分
				ctx.beginPath()
				ctx.setTextAlign('center')
				ctx.setFillStyle(color)
				ctx.setFontSize(size)
				const metrics = ctx.measureText(text)
				console.log(metrics.width)
				//文字统一偏移
				ctx.fillText(text, x + metrics.width / 2, y + 17)
			},
			// 绘制带箭头线 type:箭头朝向:bottom、right、left
			drawLine(ctx, fromX, fromY, toX, toY, color, type, isArrow = true, isDash = false) {
				ctx.beginPath()
				if (isDash) {
					ctx.setLineDash([10]);
				} else {
					ctx.setLineDash([]);
				}
				ctx.moveTo(fromX, fromY)
				ctx.lineTo(toX, toY)
				ctx.setLineWidth(1)
				ctx.setStrokeStyle(color)
				ctx.stroke()
                
                //是否绘制箭头
				if (isArrow) {
					this.drawTriangle(ctx, toX, toY, color, type)
				}
			},
			touchstart(e) {
				//点击事件有点复杂,要根据点击点、绘制位置、缩放比例判断点击了哪个节点,
				let x = e.touches[0].x
				let y = e.touches[0].y
				this.node.forEach(item => {
					// console.log("item.x * this.scale:"+item.x * this.scale)
					// console.log("item.y * this.scale:"+item.y * this.scale)
					if (x > item.x * this.scale && x < (item.x + item.w) * this.scale
						&& y > item.y * this.scale && y < (item.y + item.h) * this.scale) {
						//在范围内,根据标记定义节点类型
						console.log(item.targe)
					}
				}) 
				console.log("x:"+x + "    y:"+y)
			},
			scaleChange(e) {
				this.scale = e.detail.scale
				console.log(this.scale)
			}
		}
	}
</script>

总结:个人观点来看,uni-app端的canvas,与Android原生相比,核心原理都是找点,找到点位后执行相关绘制方法进行绘制,只不过部分方法有所不同。作为一个Android开发者,虽然暂时没具体使用过原生canvas,但对其也有了大致的了解。此外,Canvas还能实现各种效果的动画,这边初步了解了一点,后续实现了默写效果会继续更新文章。

效果展示,将就瞅瞅:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37565670/article/details/118220885

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签