创建网格(Grid/GridItem)
目录
1、概述
2、布局与约束
3、设置排列方式
3.1设置行列数量与占比
3.2、设置子组件所占行列数
3.3、设置主轴方向
3.4、在网格布局中显示数据
3.5、设置行列间距
4、构建可滚动的网格布局
5、实现简单的日历功能
6、性能优化
1、概述
网格布局是由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。网格布局具有较强的页面均分能力,子组件占比控制能力,是一种重要自适应布局,其使用场景有九宫格图片展示、日历、计算器等。
ArkUI提供了Grid容器组件和子组件GridItem,用于构建网格布局。Grid用于设置网格布局相关参数,GridItem定义子组件相关特征。Grid组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。
2、布局与约束
Grid组件为网格容器,其中容器内每一个条目对应一个GridItem组件,如下图所示。
图1 Grid与GridItem组件关系
说明
Grid的子组件必须是GridItem组件。
网格布局是一种二维布局。Grid组件支持自定义行列数和每行每列尺寸占比、设置子组件横跨几行或者几列,同时提供了垂直和水平布局能力。当网格容器组件尺寸发生变化时,所有子组件以及间距会等比例调整,从而实现网格布局的自适应能力。根据Grid的这些布局能力,可以构建出不同样式的网格布局,如下图所示。
图2 网格布局
如果Grid组件设置了宽高属性,则其尺寸为设置值。如果没有设置宽高属性,Grid组件的尺寸默认适应其父组件的尺寸。
Grid组件根据行列数量与占比属性的设置,可以分为三种布局情况:
- 行、列数量与占比同时设置:Grid只展示固定行列数的元素,其余元素不展示,且Grid不可滚动。(推荐使用该种布局方式)
- 只设置行、列数量与占比中的一个:元素按照设置的方向进行排布,超出的元素可通过滚动的方式展示。
- 行列数量与占比都不设置:元素在布局方向上排布,其行列数由布局方向、单个网格的宽高等多个属性共同决定。超出行列容纳范围的元素不展示,且Grid不可滚动。
3、设置排列方式
3.1设置行列数量与占比
通过设置行列数量与尺寸占比可以确定网格布局的整体排列方式。Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。
rowsTemplate和columnsTemplate属性值是一个由多个空格和'数字+fr'间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列的宽度。
图3 行列数量占比示例
如上图所示,构建的是一个三行三列的的网格布局,其在垂直方向上分为三等份,每行占一份;在水平方向上分为四等份,第一列占一份,第二列占两份,第三列占一份。
只要将rowsTemplate的值为'1fr 1fr 1fr',同时将columnsTemplate的值为'1fr 2fr 1fr',即可实现上述网格布局。
@Entry
@Component
struct GridLayoutPage1 {@State message: string = 'Hello World'build() {Row() {Column() {Grid() {GridItem() {Text(`1`).gridTextStyle("#1067c8ff")}GridItem() {Text(`2`).gridTextStyle("#2067c8ff")}GridItem() {Text(`3`).gridTextStyle("#3067c8ff")}GridItem() {Text(`4`).gridTextStyle("#4067c8ff")}GridItem() {Text(`5`).gridTextStyle("#5067c8ff")}GridItem() {Text(`6`).gridTextStyle("#6067c8ff")}GridItem() {Text(`7`).gridTextStyle("#7067c8ff")}GridItem() {Text(`8`).gridTextStyle("#8067c8ff")}GridItem() {Text(`9`).gridTextStyle("#9067c8ff")}}.rowsTemplate('1fr 1fr 1fr').columnsTemplate('1fr 2fr 1fr')}.width('100%')}.height('40%')}
}@Extend(Text) function gridTextStyle(value: ResourceColor) {.backgroundColor(value).width('100%').height('100%').fontSize(22).textAlign(TextAlign.Center)
}
效果如下:
3.2、设置子组件所占行列数
除了大小相同的等比例网格布局,由不同大小的网格组成不均匀分布的网格布局场景在实际应用中十分常见,如下图所示。在Grid组件中,通过设置GridItem的rowStart、rowEnd、columnStart和columnEnd可以实现如图所示的单个网格横跨多行或多列的场景。
图4 不均匀网格布局
例如计算器的按键布局就是常见的不均匀网格布局场景。如下图,计算器中的按键“0”和“=”,按键“0”横跨第一、二两列,按键“=”横跨第五、六两行。使用Grid构建的网格布局,其行列标号从1开始,依次编号。
图5 计算器
在单个网格单元中,rowStart和rowEnd属性表示指定当前元素起始行号和终点行号,columnStart和columnEnd属性表示指定当前元素的起始列号和终点列号。
所以“0”按键横跨第一列和第二列,只要将“0”对应GridItem的columnStart和columnEnd设为1和2,将“=”对应GridItem的的rowStart和rowEnd设为5和6即可。
“=”按键横跨第五行和第六行,只要将将“=”对应GridItem的的rowStart和rowEnd设为5和6即可。
@Entry
@Component
struct CalculatorLayoutPage {@State message: string = 'Hello World'build() {Row() {Column() {Grid() {GridItem() {Text(`0`).gridTextStyle2("#1067c8ff").textAlign(TextAlign.End).padding(2)}.rowStart(0).rowEnd(1).columnStart(0).columnEnd(3)GridItem() {Text(`CE`).gridTextStyle2("#2067c8ff")}GridItem() {Text(`C`).gridTextStyle2("#3067c8ff")}GridItem() {Text(`/`).gridTextStyle2("#4067c8ff")}GridItem() {Text(`X`).gridTextStyle2("#5067c8ff")}GridItem() {Text(`7`).gridTextStyle2("#6067c8ff")}GridItem() {Text(`8`).gridTextStyle2("#7067c8ff")}GridItem() {Text(`9`).gridTextStyle2("#8067c8ff")}GridItem() {Text(`-`).gridTextStyle2("#9067c8ff")}GridItem() {Text(`4`).gridTextStyle2("#A067c8ff")}GridItem() {Text(`5`).gridTextStyle2("#B067c8ff")}GridItem() {Text(`6`).gridTextStyle2("#C067c8ff")}GridItem() {Text(`+`).gridTextStyle2("#D067c8ff")}GridItem() {Text(`1`).gridTextStyle2("#E067c8ff")}GridItem() {Text(`2`).gridTextStyle2("#F067c8ff")}GridItem() {Text(`3`).gridTextStyle2("#F167c8ff")}GridItem() {Text(`=`).gridTextStyle2("#F267c8ff")}.rowStart(5).rowEnd(6).columnStart(3).columnEnd(3)GridItem() {Text(`0`).gridTextStyle2("#F367c8ff")}.columnStart(0).columnEnd(1)GridItem() {Text(`.`).gridTextStyle2("#F467c8ff")}}.margin(12).rowsGap(12).columnsGap(8).rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr').columnsTemplate('1fr 1fr 1fr 1fr')}.width('100%')}.height('80%')}
}@Extend(Text) function gridTextStyle2(value: ResourceColor) {.backgroundColor(value).width('100%').height('100%').fontSize(40).textAlign(TextAlign.Center).borderRadius(5)
}
效果如下:
3.3、设置主轴方向
使用Grid构建网格布局时,若没有设置行列数量与占比,可以通过layoutDirection可以设置网格布局的主轴方向,决定子组件的排列方式。此时可以结合minCount和maxCount属性来约束主轴方向上的网格数量。
图6 主轴方向示意图
当前layoutDirection设置为Row时,先从左到右排列,排满一行再排一下一行。当前layoutDirection设置为Column时,先从上到下排列,排满一列再排一下一列,如上图所示。此时,将maxCount属性设为3,表示主轴方向上最大显示的网格单元数量为3。
@Entry
@Component
struct GridLayoutPage2 {@State array: Array<string> = ['1', '2', '3', '4', '5', '6', '7', '8', '9']build() {Row() {Column() {Grid() {ForEach(this.array, (item: string, index) => {GridItem() {Text(item).gridTextStyle_page2('#67c8ff')}}, item => item)}.rowsGap(12).columnsGap(8).margin(4).maxCount(3).minCount(3).layoutDirection(GridDirection.Column)}.width('100%')}.height('40%')}
}@Extend(Text) function gridTextStyle_page2(value: ResourceColor) {.backgroundColor(value).width('30%').height('30%').fontSize(22).textAlign(TextAlign.Center)
}
效果如下:
说明
1. layoutDirection属性仅在不设置rowsTemplate和columnsTemplate时生效,此时元素在layoutDirection方向上排列。
2. 仅设置rowsTemplate时,Grid主轴为水平方向,交叉轴为垂直方向。
2. 仅设置columnsTemplate时,Grid主轴为垂直方向,交叉轴为水平方向。
3.4、在网格布局中显示数据
网格布局采用二维布局的方式组织其内部元素,如下图所示。
图7 通用办公服务
Grid组件可以通过二维布局的方式显示一组GridItem子组件。
@Entry
@Component
struct GridLayoutPage3 {@State message: string = 'Hello World'build() {Row() {Column() {Grid() {GridItem() {Text('会议')}.backgroundColor('#1067c8ff')GridItem() {Text('签到')}.backgroundColor('#3067c8ff')GridItem() {Text('培训')}.backgroundColor('#5067c8ff')GridItem() {Text('打印')}.backgroundColor('#7067c8ff')}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr')}.width('100%').height('40%')}.height('100%').alignItems(VerticalAlign.Top)}
}
对于内容结构相似的多个GridItem,通常更推荐使用循环渲染ForEach语句中嵌套GridItem的形式,来减少重复代码。
@Entry
@Component
struct GridLayoutPage3 {@State message: Bean[] = [{ title: '会议', color: '#1067c8ff' },{ title: '签到', color: '#3067c8ff' },{ title: '培训', color: '#5067c8ff' },{ title: '打印', color: '#7067c8ff' }]build() {Row() {Column() {Grid() {ForEach(this.message, (item: Bean) => {GridItem() {Text(item.title).backgroundColor(item.color).width('100%').height('100%').textAlign(TextAlign.Center)}}, item => JSON.stringify(item))}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr')}.width('100%').height('40%')}.height('100%').alignItems(VerticalAlign.Top)}
}class Bean {title: stringcolor: ResourceColor
}
效果同上。
3.5、设置行列间距
在两个网格单元之间的网格横向间距称为行间距,网格纵向间距称为列间距,如下图所示。
图8 网格的行列间距
通过Grid的rowsGap和columnsGap可以设置网格布局的行列间距。
@Entry
@Component
struct GridLayoutPage3 {@State message: Bean[] = [{ title: '会议', color: '#1067c8ff' },{ title: '签到', color: '#3067c8ff' },{ title: '培训', color: '#5067c8ff' },{ title: '打印', color: '#7067c8ff' }]build() {Row() {Column() {Grid() {ForEach(this.message, (item: Bean) => {GridItem() {Text(item.title).backgroundColor(item.color).width('100%').height('100%').textAlign(TextAlign.Center)}}, item => JSON.stringify(item))}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr').rowsGap(10).columnsGap(10).margin(10)}.width('100%').height('40%').backgroundColor('#eee')}.height('100%').alignItems(VerticalAlign.Top)}
}class Bean {title: stringcolor: ResourceColor
}
效果如下:
4、构建可滚动的网格布局
可滚动的网格布局常用在文件管理、购物或视频列表等页面中,如下图所示。在设置Grid的行列数量与占比时,如果仅设置行、列数量与占比中的一个,即仅设置rowsTemplate或仅设置columnsTemplate属性,网格单元按照设置的方向排列,超出Grid显示区域后,Grid拥有可滚动能力。
图9 横向可滚动网格布局
如果设置的是columnsTemplate,Grid的滚动方向为垂直方向;如果设置的是rowsTemplate,Grid的滚动方向为水平方向。
如上图所示的横向可滚动网格布局,只要设置rowsTemplate属性的值且不设置columnsTemplate属性,当内容超出Grid组件宽度时,Grid可横向滚动进行内容展示。
@Entry
@Component
struct GridScrollLayoutPage {@State services: Array<string> = ['直播', '进口', '国外', '乡里', '本地', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']color: ResourceColor[] = [Color.Blue, Color.Green, Color.Orange, Color.Pink, Color.Yellow]build() {Column({ space: 5 }) {Grid() {ForEach(this.services, (service: string, index) => {GridItem() {Text(service).backgroundColor(this.color[index % this.color.length]).fontColor(Color.White).width(72).height(72).fontSize(24).borderRadius(8).textAlign(TextAlign.Center).borderRadius(36)}.width('25%')}, service => service)}.rowsTemplate('1fr 1fr') // 只设置rowsTemplate属性,当内容超出Grid区域时,可水平滚动。.rowsGap(15).columnsGap(12).height('25%')}.borderColor(Color.Pink).borderWidth(1).borderRadius(8).margin(8).backgroundColor("#1067c8ff")}
}
5、实现简单的日历功能
import hilog from '@ohos.hilog';@Entry
@Component
struct CalendarLayoutPage {private scroller: Scroller = new Scroller()private headLabel: string[] = ['一', '二', '三', '四', '五', '六', '日']private curDate: Date;@State curDateStr: string = ''@State dateArray: number[] = []aboutToAppear() {let date = new Date();this.curDate = date;this.changeMonthData()}changeMonthData() {let monthLength = this.getMonthLength(this.curDate);this.dateArray = []for (let index = 0; index < monthLength; index++) {this.dateArray.push(index + 1)}this.curDateStr = `${this.curDate.getFullYear()}-${this.curDate.getMonth() + 1}`}private nextMonth() {this.curDate.setMonth(this.curDate.getMonth() + 1)}private prevMonth() {this.curDate.setMonth(this.curDate.getMonth() - 1)}private getMonthLength(date: Date): number {let copyDate = new Date(date.getFullYear(), date.getMonth() + 1, 0)return copyDate.getDate()}build() {Row() {Column() {Text(this.curDateStr).backgroundColor(Color.Pink).fontColor(Color.White).height(48).padding({ left: 24, right: 24 }).borderRadius(24)Row({ space: 8 }) {ForEach(this.headLabel, (item) => {Text(item).fontSize(14).layoutWeight(1).textAlign(TextAlign.Center).height('40%').borderRadius(26).backgroundColor('#67c8ff')}, item => JSON.stringify(item))}.height(52).backgroundColor('#999').margin({top: 24})Grid() {ForEach(this.dateArray, (item) => {GridItem() {Button(item + "").width(52).height(52).borderWidth(1).borderColor('#67c8ff')}}, item => JSON.stringify(item))}.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr').columnsGap(5).rowsGap(5).margin({ top: 12 }).height('40%')Row({ space: 20 }) {Button('上一页').onClick(() => {this.prevMonth()this.changeMonthData()// this.scroller.scrollPage({// next: false// })})Button('下一页').onClick(() => {this.nextMonth()this.changeMonthData()// this.scroller.scrollPage({// next: true// })})}}.width('100%').backgroundColor('#eee').borderRadius(24)}.height('100%').alignItems(VerticalAlign.Top).margin({top: 48, left: 12, right: 12})}
}
通过 @State dateArray来刷新UI,当点击前一页的时候,当前月份减少1,然后改变dateArray的数据,触发UI更新;点击下一页同理。效果如下:
6、性能优化
与长列表的处理类似,循环渲染适用于数据量较小的布局场景,当构建具有大量网格项的可滚动网格布局时,推荐使用数据懒加载方式实现按需迭代加载数据,从而提升列表性能。
关于按需加载优化的具体实现可参考数据懒加载章节中的示例。
当使用懒加载方式渲染网格时,为了更好的滚动体验,减少滑动时出现白块,Grid组件中也可通过cachedCount属性设置GridItem的预加载数量,只在懒加载LazyForEach中生效。
设置预加载数量后,会在Grid显示区域前后各缓存cachedCount*列数个GridItem,超出显示和缓存范围的GridItem会被释放。
Grid() {LazyForEach(this.dataSource, item => {GridItem() {...}})
}
.cachedCount(3)
说明
cachedCount的增加会增大UI的CPU、内存开销。使用时需要根据实际情况,综合性能和用户体验进行调整。
相关文章:

创建网格(Grid/GridItem)
目录 1、概述 2、布局与约束 3、设置排列方式 3.1设置行列数量与占比 3.2、设置子组件所占行列数 3.3、设置主轴方向 3.4、在网格布局中显示数据 3.5、设置行列间距 4、构建可滚动的网格布局 5、实现简单的日历功能 6、性能优化 1、概述 网格布局是由“行”和“列”分…...
思科路由器忘记密码怎么重置
断电重启路由器,在开机过程中按下CtrlPause/break,或者只按下Pause/break(没有测试),在PT(Cisco Packet Tracert)中则需要按CtrlC。路由器会进入rommon >模式。 切换到0x2142模式࿰…...

JVM基础(2)——JVM内存模型
一、简介 JVM会加载类到内存中,所以 JVM 中必然会有一块内存区域来存放我们写的那些类。Java中有类对象、普通对象、本地变量、方法信息等等各种对象信息,所以JVM会对内存区域进行划分: JDK1.8及以后,上图中的方法区变成了Metasp…...

使用 Process Explorer 和 Windbg 排查软件线程堵塞问题
目录 1、问题说明 2、线程堵塞的可能原因分析 3、使用Windbg和Process Explorer确定线程中发生了死循环 4、根据Windbg中显示的函数调用堆栈去查看源码,找到问题 4.1、在Windbg定位发生死循环的函数的方法 4.2、在Windbg中查看变量的值去辅助分析 4.3、是循环…...

做科技类的展台3d模型用什么材质比较好---模大狮模型网
对于科技类展台3D模型,以下是几种常用的材质选择: 金属材质:金属材质常用于科技展台的现代感设计,如不锈钢、铝合金或镀铬材质。金属材质可以赋予展台一个科技感和高档感,同时还可以反射光线,增加模型的真实…...

EasyExcel简单实例(未完待续)
EasyExcel简单实例 准备工作场景一:读取 Student 表需求1:简单读取需求2:读取到异常信息时不中断需求3:读取所有的sheet工作表需求4:读取指定的sheet工作表需求5:从指定的行开始读取 场景二:写入…...

ROS2学习笔记一:安装及测试
目录 前言 1 ROS2安装与卸载 1.1 安装虚拟机 1.2 ROS2 humble安装 2 ROS2测试 2.1 topic测试 2.2 小海龟测试 2.3 RQT可视化 2.4 占用空间 前言 ROS2的前身是ROS,ROS即机器人操作系统(Robot Operating System),ROS为了“提高机器人…...

Xcode14.3.1真机调试iOS17的方法
Hello,大家好我是咕噜铁蛋!Xcode 是苹果官方开发工具,它提供了完整的开发环境和工具集,支持开发 iOS、macOS、watchOS 和 tvOS 应用程序。对于 iOS 开发者来说,Xcode 是必备的工具之一。而随着 iOS 系统的不断更新和升…...

主流大语言模型从预训练到微调的技术原理
引言 本文设计的内容主要包含以下几个方面: 比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节:tokenizer、位置编码、Layer Normalization、激活函数等。大语言模型的分布式训练技术:数据并行、张量模型并行、流水线并行、3D 并行、零冗余优…...

Linux中vim查看文件某内容
一、编辑文件命令 [rootyinheqilin ~]# vim test.txt 1,在编辑的文件中连续按2次键盘的【g】键,光标会移动到文档开头第一行 2,输入一个大写 G,光标会跳转到文件的最后一行第一列(末行) 二、查看文件内容命令 gre…...
阿里云提示服务器ip暴露该怎么办?-速盾网络(sudun)
当阿里云提示服务器IP暴露的时候,这意味着您的服务器可能面临安全风险,因为黑客可以通过知道服务器的IP地址来尝试入侵您的系统。在这种情况下,您应该立即采取措施来保护您的服务器和数据。以下是一些建议: 更改服务器IP地址&…...

IP地址的网络安全防护和预防
网络安全对于保护个人和组织的信息资产至关重要,而IP地址是网络通信的基础。在这篇文章中,IP数据云将探讨IP地址的网络安全防护和预防措施,以确保网络的安全性和可靠性。 IP地址是互联网上每个设备在网络中的唯一标识符。有IPv4和IPv6两种类…...

数据挖掘在制造业中的预测与优化应用
随着大数据时代的到来,数据挖掘技术在各行各业的应用日益广泛,尤其在制造业中,其对于提升生产效率、降低运营成本、优化供应链管理等方面发挥着不可替代的作用。本文将探讨数据挖掘在制造业中的预测与优化应用,通过深入剖析实际案…...

Java面试之并发篇(一)
1、前言 本篇主要总结JAVA面试中关于并发相关的高频面试题。本篇的面试题基于网络整理,和自己编辑。在不断的完善补充哦。 2、简述程序、进程、线程、的基本概念? 2.1、程序 程序,是含有指令和数据的文件,被存储在磁盘或其他的…...

分布式全局id
分布式全局id snowflake 算法是 twitter 开源的分布式 id 生成算法,采用 Scala 语言实现,是把一个 64 位的 long 型的 id,1 个 bit 是不用的,用其中的 41 bits 作为毫秒数,用 10 bits 作为工作机器 id,12 …...

springboot 房屋租赁系统
spring boot mysql mybatis 前台后端...

TypeScript接口、对象
目录 1、TypeScript 接口 1.1、实例 1.2、联合类型和接口 1.3、接口和数组 1.4、接口和继承 1.5、单继承实例 1.6、多继承实例 2、TypeScript 对象 2.2、对象实例 2.3、TypeScript类型模板 2.4、鸭子类型(Duck typing) 1、TypeScript 接口 接口…...

Flask 菜品管理
common/libs/Helper.py getDictFilterField() 方法 用于在web/templates/food/index.html中展示菜品分类 如何能够通过food里面的cat_id获取分类信息呢?只能通过for循环,这样会很麻烦,所以定义了这个方法。 这个方法可以的查询返回结果…...

亚马逊实时 AI 编程助手 CodeWhisperer使用体验
文章目录 1:什么是CodeWhisperer ?2:试用3:上手体验 1:什么是CodeWhisperer ? 最近ChatGPT展现出强大AI能力给我们带来了深刻的影响,AI现在不是一个概念,基于AI的产品一定在各行各业…...
[机缘参悟-123] :实修 - 东西方各种思想流派实修的要旨与比较?
目录 前言: 一、东方各种思想流派实修的要旨? 1.1 儒、释、道、法的主要思想 1.2 儒、释、道、法各种追求的目标 1.3 儒、释、道、法各自修行的法门或修行的途径 二、西方灵修的各种派别的要旨? 2.0 西方灵修的各种派别 2.1 玛雅星系…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...