HarmonyOS Codelab 优秀样例——购物应用,体验一次开发多端部署魅力
一. 样例介绍
本篇Codelab基于自适应布局和响应式布局,实现购物应用在手机、折叠屏、平板不同屏幕尺寸设备上按不同设计显示。通过三层工程结构组织代码,实现一次开发,多端部署 。
手机运行效果如图所示:
折叠屏运行效果图:
平板运行效果图:
相关概念
- 一次开发,多端部署:一套代码工程,一次开发上架,多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用。
- 自适应布局:当外部容器大小发生变化时,元素可以根据相对关系自动变化以适应外部容器变化的布局能力。相对关系如占比、固定宽高比、显示优先级等。当前自适应布局能力有7种:拉伸能力、均分能力、占比能力、缩放能力、延伸能力、隐藏能力、折行能力。自适应布局能力可以实现界面显示随外部容器大小连续变化。
- 响应式布局:当外部容器大小发生变化时,元素可以根据断点、栅格或特定的特征(如屏幕方向、窗口宽高等)自动变化以适应外部容器变化的布局能力。当前响应式布局能力有3种:断点、媒体查询、栅格布局。
- GridRow:栅格容器组件,仅可以和栅格子组件(GridCol)在栅格布局场景中使用。
- GridCol:栅格子组件,必须作为栅格容器组件(GridRow)的子组件使用。
完整示例:gitee源码地址
二. 环境搭建
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
软件要求
- DevEco Studio版本:DevEco Studio 3.1 Release及以上版本。
- HarmonyOS SDK版本:API version 9及以上版本。
硬件要求
- 设备类型:华为手机或运行在DevEco Studio上的华为手机设备模拟器。
- HarmonyOS系统:3.1.0 Developer Release及以上版本。
环境搭建
- 安装DevEco Studio,详情请参考下载和安装软件。
- 设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
- 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
- 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
- 开发者可以参考以下链接,完成设备调试的相关配置:
- 使用真机进行调试
- 使用模拟器进行调试
三.代码结构解读
本篇Codelab只对核心代码进行讲解,common为公共能力层,feature为功能模块层,本示例分为六个模块,product则为产品层。对于完整代码,我们会在源码下载或gitee中提供。
├──common/src/main/ets // 公共能力层
│ ├──bean
│ │ ├──CommodityModel.ets // 商品数据实体类
│ │ ├──OrderModel.ets // 订单数据实体类
│ │ └──ProductModel.ets // 购物车商品数据实体类
│ ├──components
│ │ ├──CommodityList.ets // 商品列表组件
│ │ ├──CounterProduct.ets // 数量加减组件
│ │ └──EmptyComponent.ets // 无数据显示组件
│ ├──constants
│ │ ├──BreakpointConstants.ets // 断点常量类
│ │ ├──GridConstants.ets // 栅格常量类
│ │ └──StyleConstants.ets // 样式常量类
│ ├──utils
│ │ ├──BreakpointSystem.ets // 断点工具类
│ │ ├──CommonDataSource.ets // 数据封装类
│ │ ├──LocalDataManager.ets // 数据操作管理类
│ │ ├──Logger.ets.ets // 日志工具类
│ │ └──Utils.ets // 方法工具类
│ └──viewmodel
│ └──ShopData.ets // 商品应用数据
├──features // 功能模块层
│ ├──commoditydetail/src/main/ets // 商品详情内容区
│ │ ├──bean
│ │ │ └──TypeModel.ets // 实体类
│ │ ├──components
│ │ │ ├──CapsuleGroupButton.ets // 自定义按钮组件
│ │ │ ├──CommodityDetail.ets // 商品详情组件
│ │ │ └──SpecificationDialog.ets // 商品规格弹框
│ │ ├──constants
│ │ │ └──CommodityConstants.ets // 商品详情区常量类
│ │ └──viewmodel
│ │ └──CommodityDetailData.ets // 商品详情数据类
│ ├──home/src/main/ets // 首页内容区
│ │ ├──components
│ │ │ └──Home.ets // 首页内容组件
│ │ └──viewmodel
│ │ └──HomeData.ets // 首页数据
│ ├──newproduct/src/main/ets // 新品内容区
│ │ ├──components
│ │ │ └──NewProduct.ets // 新品内容组件
│ │ └──viewmodel
│ │ └──NewProductData.ets // 新品数据
│ ├──orderdetail/src/main/ets // 订单相关内容区
│ │ ├──components
│ │ │ ├──AddressInfo.ets // 收件人信息组件
│ │ │ ├──CommodityOrderItem.ets // 商品订单信息组件
│ │ │ ├──CommodityOrderList.ets // 商品订单列表组件
│ │ │ ├──ConfirmOrder.ets // 确认订单组件
│ │ │ ├──HeaderBar.ets // 标题组件
│ │ │ ├──OrderDetailList.ets // 订单分类列表组件
│ │ │ ├──OrderListContent.ets // 订单分类列表内容组件
│ │ │ └──PayOrder.ets // 支付订单组件
│ │ ├──constants
│ │ │ └──OrderDetailConstants.ets // 订单区常量类
│ │ └──viewmodel
│ │ └──OrderData.ets // 订单数据
│ ├──personal/src/main/ets // 我的内容区
│ │ ├──bean
│ │ │ └──IconButtonModel.ets // 按钮图标实体类
│ │ ├──components
│ │ │ ├──IconButton.ets // 图片按钮组件
│ │ │ ├──LiveList.ets // 直播列表组件
│ │ │ └──Personal.ets // 我的内容组件
│ │ ├──constants
│ │ │ └──PersonalConstants.ets // 我的常量类
│ │ └──viewmodel
│ │ └──PersonalData.ets // 我的数据
│ └──shopcart/src/main/ets // 购物车内容区
│ ├──components
│ │ └──ShopCart.ets // 购物车内容组件
│ └──constants
│ └──ShopCartConstants.ets // 购物车常量类
└──products // 产品层
└──phone/src/main/ets // 支持手机、平板
├──constants
│ └──PageConstants.ets // 页面常量类
├──entryability
│ └──EntryAbility.ets // 程序入口类
├──pages
│ ├──CommodityDetailPage.ets // 订单详情页
│ ├──ConfirmOrderPage.ets // 确认订单页
│ ├──MainPage.ets // 主页
│ ├──OrderDetailListPage.ets // 订单分类列表页
│ ├──PayOrderPage.ets // 支付订单页
│ └──SplashPage.ets // 启动过渡页
└──viewmodel
└──MainPageData.ets // 主页数据
四. 应用主框架
4.1 启动页
在工程pages目录中,选中Index.ets,点击鼠标右键 > Refactor > Rename,改名为SplashPage.ets。改名后,修改工程entryability目录下EntryAbility.ets文件中windowStage.loadContent方法第一个参数为pages/SplashPage。在该页面的周期函数aboutToAppear里添加一个2秒的定时任务跳转到主页实现。
// EntryAbility.ets
windowStage.loadContent('pages/SplashPage', (err, data) => {if (err.code) {...}
});// SplashPage.ets
build() {Column() {...}.height(StyleConstants.FULL_HEIGHT).width(StyleConstants.FULL_WIDTH).backgroundColor($r('app.color.page_background'))
}aboutToAppear() {this.breakpointSystem.register();this.timeOutId = setTimeout(() => {
router.replaceUrl({ url: PageConstants.MAIN_PAGE_URL }).catch(err => {
Logger.error(JSON.stringify(err));})}, PageConstants.DELAY_TIME);
}aboutToDisappear() {this.breakpointSystem.unregister();clearTimeout(this.timeOutId);
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
4.2 主页
本篇Codelab主页由Tabs容器组件和四个TabContent子组件组成,四个TabContent页签的内容视图分别为首页(Home)、新品(NewProduct)、购物车(ShopCart)、我的(Personal)。根据用户使用场景,通过响应式布局的媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值,设置Tabs的页签位置,lg断点如平板则显示侧边栏,其他断点的则显示底部栏。
/// MainPage.ets
build() {Column() {Tabs({
barPosition: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
BarPosition.Start : BarPosition.End,
index: this.currentPageIndex
}) { ... .barWidth(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?$r('app.float.bar_width') : StyleConstants.FULL_WIDTH).barHeight(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
StyleConstants.SIXTY_HEIGHT : $r('app.float.vp_fifty_six')).vertical(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG)}.backgroundColor($r('app.color.page_background'))
}
主页页面展示:
五. 页面介绍
5.1 首页标签页
首页标签页通过自适应布局的均分、拉伸等能力实现搜索框、分类等布局,通过响应式布局的媒体查询、断点能力设置轮播图数、商品列表数。
通过响应式布局的媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值,设置商品列表列数和轮播图数,lg断点显示4列3张轮播图,md断点显示3列2张轮播图,sm断点显示2列1张轮播图。
// Home.ets
@Builder CustomSwiper() {Swiper() {ForEach(swiperImage, (item: Resource) => {Image(item).width(StyleConstants.FULL_WIDTH).aspectRatio(StyleConstants.IMAGE_ASPECT_RATIO)}, item => JSON.stringify(item))}.itemSpace(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ? 0 :
StyleConstants.ITEM_SPACE).indicator(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM).displayCount(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
StyleConstants.DISPLAY_THREE :(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ? StyleConstants.DISPLAY_TWO :
StyleConstants.DISPLAY_ONE))
}// Home.ets
CommodityList({
commodityList: $commodityList,
column: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? StyleConstants.DISPLAY_FOUR :(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ?
StyleConstants.DISPLAY_THREE : StyleConstants.DISPLAY_TWO),onClickItem: (data: Commodity) => this.onClickItem(data)
})// CommodityList.ets
build() {if (this.commodityList.length > 0) {List({ space: StyleConstants.TWELVE_SPACE }) {LazyForEach(new CommonDataSource(this.commodityList), (item: Commodity) => {...}, item => JSON.stringify(item))}....lanes(this.column)} else {EmptyComponent({ outerHeight: StyleConstants.FIFTY_HEIGHT })}
}
使用自适应布局的均分能力,在Flex布局中设置主轴上的对齐方式为FlexAlign.SpaceAround,使循环渲染的组件之间距离相同,第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
// Home.ets
@Builder ActivityTitle() {Flex({ justifyContent: FlexAlign.SpaceAround }) {ForEach(activityTitle, (item: ActivityTitleModel, index: number) => {Flex({
direction: FlexDirection.Column,
justifyContent: FlexAlign.Center,
alignItems: ItemAlign.Center
}) {...}}, item => JSON.stringify(item))}...
}
手机运行效果图:
折叠屏运行效果图
平板运行效果图
5.2 新品标签页
新品标签页由轮播图、分类、新品列表组成,通过响应式布局的媒体查询、断点能力和自适应布局的均分能力,实现不同设备类型显示不同效果,实现逻辑同主页。
通过响应式布局的媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值设置新品列表,sm断点显示2列,md、lg断点显示3列。
// NewProduct.ets
@Builder ProductList() {List({ space: StyleConstants.TWELVE_SPACE }) {LazyForEach(new CommonDataSource(productData), (item: ProductDataModel) => {ListItem() {...}, item => JSON.stringify(item))}.lanes(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ?
StyleConstants.DISPLAY_TWO : StyleConstants.DISPLAY_THREE).padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
}
手机运行效果图:
折叠屏运行效果图
平板运行效果图
5.3 购物车标签页
购物车标签页,由购物车列表和商品列表组成,商品列表实现逻辑同主页的商品列表,购物车列表使用自适应布局的均分能力实现。
// ShopCart.ets
@Builder CartItem(item: Product, index: number) {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {...Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceAround }) {Text($r('app.string.commodity_piece_description', item.name, item.description))...Text(`${Object.values(item.specifications).join(',')}`)...Flex({ justifyContent: FlexAlign.SpaceBetween }) {Text() {...}CounterProduct({
count: item.count,onNumberChange: (num: number) => {this.onChangeCount(num, item);}})}}...}
}
手机运行效果图:
折叠屏运行效果图
平板运行效果图
5.4 我的标签页
我的标签页主要由个人信息、我的订单、文字图片按钮、直播列表组成,直播列表实现方案同主页商品列表,其他则使用自适应布局的均分能力,Flex布局设置主轴上的对齐方式为FlexAlign.SpaceAround。
// Personal.ets
@Builder Order() {Flex({direction: FlexDirection.Column}) {Flex({
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {Text($r('app.string.order_mine')).fontSize($r('app.float.middle_font_size'))Row() {...}...})}Flex({
justifyContent: FlexAlign.SpaceAround,
alignItems: ItemAlign.Center
}) {ForEach(this.orderIconButton, (iconButton: IconButtonModel) => {IconButton({
props: iconButton,
click: this.onOrderButtonClick.bind(this, iconButton.key)})}, (iconButton) => JSON.stringify(iconButton))}.width(StyleConstants.FULL_WIDTH)
}@Builder IconDock(buttons: IconButtonModel[]) {Flex({
justifyContent: FlexAlign.SpaceAround,
alignItems: ItemAlign.Center
}) {ForEach(buttons, (iconButton: IconButtonModel) => {IconButton({
props: iconButton})}, (iconButton) => JSON.stringify(iconButton))}.height($r('app.float.icon_dock_height')).padding($r('app.float.vp_twelve')).cardStyle()
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.5 商品详情页
商品详情页整体由轮播图、商品信息、底部按钮栏组成,通过响应式布局能力的栅格布局,实现不同设备类型显示不同的效果,并通过自适应布局的拉伸能力,设置flexGrow属性使按钮位于底部。
- 在sm断点下,轮播图占4个栅格,商品信息占4个栅格,底部按钮栏占4个栅格。
- 在md断点下,轮播图占8个栅格,商品信息占8个栅格,底部按钮栏占8个栅格。
- 在lg断点下,轮播图占12个栅格,商品信息占8个栅格偏移2个栅格,底部按钮栏占8个栅格偏移2个栅格。
// CommodityDetail.ets
build() {Stack({ alignContent: Alignment.TopStart }) {Flex({ direction: FlexDirection.Column }) {Scroll() {GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
},
gutter: GridConstants.GUTTER_TWELVE
}) {GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_TWELVE }
}) {this.CustomSwiper(this.info.images)}GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {Column() {...}}}}.flexGrow(StyleConstants.FLEX_GROW)GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
},
gutter: GridConstants.GUTTER_TWELVE
}) {GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO } }) {this.BottomMenu()}}}...}
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.6 订单确认页
订单确认页由上方收件信息、订单信息、底部的总价和提交订单按钮组成,通过响应式布局的栅格布局,实现不同设备类型显示不同的效果,并通过自适应布局的拉伸能力,设置flexGrow属性使总价和提交订单按钮位于底部。
- 在sm断点下,上方收件信息和订单信息占4个栅格,底部总价占2个栅格,底部提交订单按钮占2个栅格。
- 在md断点下,上方收件信息和订单信息占8个栅格,底部总价占2个栅格,底部按钮占3个栅格偏移3个栅格。
- 在lg断点下,上方收件信息和订单信息占8个栅格偏移2个栅格,底部总价占2个栅格偏移2个栅格,底部按钮占3个栅格偏移3个栅格。
// ConfirmOrder.ets
build() {Flex({ direction: FlexDirection.Column }) {HeaderBar({...})Column(){Scroll() {GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {Column() {AddressInfo()CommodityOrderList()}}}}.scrollBar(BarState.Off)}.flexGrow(StyleConstants.FLEX_GROW).padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
},
gutter: GridConstants.GUTTER_TWELVE
}) {GridCol({
span: {
sm: GridConstants.SPAN_TWO,
md: GridConstants.SPAN_TWO,
lg: GridConstants.SPAN_TWO
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {Text($r('app.string.bottom_bar_amount', this.amount))...}GridCol({
span: {
sm: GridConstants.SPAN_TWO,
md: GridConstants.SPAN_THREE,
lg: GridConstants.SPAN_THREE
},
offset: {
md: GridConstants.OFFSET_THREE,
lg: GridConstants.OFFSET_THREE
}
}) {Button($r('app.string.bottom_bar_button'))...}}...}...
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.7 订单支付页
订单支付页整体由上方订单信息和底部的去支付按钮组成,通过使用响应式布局的栅格布局实现不同设备类型显示不同效果,并通过自适应布局的拉伸能力,设置flexGrow属性使去支付按钮位于底部。
- 在sm断点下,上方订单信息占4个栅格,底部去支付按钮占2个栅格偏移2个栅格。
- 在md断点下,上方订单信息占8个栅格,底部去支付按钮占2个栅格偏移6个栅格。
- 在lg断点下,上方订单信息占8个栅格偏移2个栅格,底部去支付按钮占2个栅格偏移8个栅格。
// PayOrder.ets
build() {Flex({ direction: FlexDirection.Column }) {HeaderBar({...})Stack({ alignContent: Alignment.TopStart }) {...Column() {Scroll() {GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {Column() {this.OrderStatus()...}}}}.scrollBar(BarState.Off)}.padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })}.flexGrow(StyleConstants.FLEX_GROW)GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {GridCol({
span: {
sm: GridConstants.SPAN_TWO,
md: GridConstants.SPAN_TWO,
lg: GridConstants.SPAN_TWO
},
offset: {
sm: GridConstants.OFFSET_TWO,
md: GridConstants.OFFSET_SIX,
lg: GridConstants.OFFSET_EIGHT
}
}) {this.BottomBar()}}}...
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.8 订单列表页
订单列表页整体布局通过响应式布局的栅格布局,实现不同设备类型显示不同的效果。
- 在sm断点下,整体UX占4个栅格。
- 在md断点下,整体UX占8个栅格。
- 在lg断点下,整体UX占8个栅格偏移2个栅格。
// OrderListContent.ets
build() {Column() {Scroll() {GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {Column() {...}}}}.scrollBar(BarState.Off)}...
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
六. 总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
- 针对不同屏幕尺寸的设备完成一次开发,多端部署页面设计。
- 按照三层工程结构划分模块、组织代码。
- 通过自适应布局、响应式布局、栅格布局实现一次开发,多端部署。
相关文章:

HarmonyOS Codelab 优秀样例——购物应用,体验一次开发多端部署魅力
一. 样例介绍 本篇Codelab基于自适应布局和响应式布局,实现购物应用在手机、折叠屏、平板不同屏幕尺寸设备上按不同设计显示。通过三层工程结构组织代码,实现一次开发,多端部署 。 手机运行效果如图所示: 折叠屏运行效果图&#x…...

音频基本知识
声音传播方式: 1)声音的传播需要介质,在真空中不能传播; 2)声波属于纵波,即如下图传播方向与振动方向一致; 声音速度: 1)常温常压下,一般空气速度为340m/s; 2)温度越高,声速越大; 3)液体、固体的传播速度比空气快; 人耳可接收到的频域范围: 1)通常范围…...

小程序中如何给会员卡设置到期时间
通过设置会员卡到期时间,可以有效地管理会员卡的使用周期,提供更好的会员服务体验。下面将介绍一种常见的给会员卡设置到期时间的方法。 1. 找到指定的会员卡。在管理员后台->会员管理处,找到需要设置到期时间的会员卡。也支持对会员卡按…...
Cookie与Session的区别及如何选择
目录 Cookie Session 如何选择 在网站开发中,Cookie与Session是两种常见的数据管理方式,它们在不同情况下有各自的优势和劣势。在这篇文章中,我们将深入了解Cookie与Session之间的区别,并提供了一些建议,帮助您在实…...

【快手小玩法-弹幕游戏】开发者功能测试报告提交模板
背景 快手有明确的要求,准入和准出更加严格,要求有明确的测试报告。格式如下: *本文参考字节wiki:CP侧测试报告模板(复制填写轻雀文档) 其他文章推荐:【抖音小玩法-弹幕游戏】开发者功能测试报告提交模板 一、前言…...
微信小程序在线阅读系统微信小程序设计与实现
摘 要:信息技术永远是改变生活的第一种创新方式,各种行业的发展更是脱离不了科技化的支持。原本传统的行业正在被科技行业的切入悄悄的发生变化。就拿我们生活当中常见的事情举例而言,在外卖行业还没有发展的快速的时候,方便面等速…...

【OpenCV入门】第七部分——图像的几何变换
文章结构 缩放dsize参数实现缩放fx参数和fy参数实现缩放 翻转仿射变换平移旋转倾斜 透视cmath模块 缩放 通过resize()方法可以随意更改图像的大小比例: dst cv2.resize(src, dsize, fx, fy, interpolation)src: 原始图像dsize: 输出图像的…...
淘宝app商品详情原数据接口API(支持高并发请求/免费测试)
item_get_app-获得淘宝app商品详情原数据 一、引言 随着移动互联网的迅速发展,移动电商应用的需求也在不断增长。淘宝作为中国最大的电商平台之一,每天需要处理大量的商品数据和用户访问请求。为了提供更加优质的用户体验,淘宝开放了商品详…...

JS中的new操作符
文章目录 JS中的new操作符一、什么是new?二、new经历了什么过程?三、new的过程分析四、总结 JS中的new操作符 参考:https://www.cnblogs.com/buildnewhomeland/p/12797537.html 一、什么是new? 在JS中,new的作用是通过…...
文件编辑器、用户管理,嘎嘎学
打开文件 vim # 首先你先得下载这个插件 yum install -y vim vim 文件名 进入编辑模式 i #在光标所在处进入编辑模式 a #在当前光标后面进入编辑模式 o #在光标的下一行进入编辑模式 I #在光标所在处行首进入编辑模式 A #在光标所在处行尾进入编辑模式 O #在光标的上一…...
Java获取当前类名的两种方法
适用于非静态方法:this.getClass().getName() 适用于静态方法:Thread.currentThread().getStackTrace()[1].getClassName() 获取类名: 1、在类的实例中可使用this.getClass().getName();但在static method中不能使用该方法; 2、在…...

windows系统开机自启打开指定网页
windows系统开机自启打开指定网页 1、在电脑桌面右击新建快捷方式,输入想要开机打开的网址 2、点击下一步输入自己想要命名的名字 3、使用快捷键winR运行,输入shell:startup,点击确定 4、把在桌面创建快捷方式拉到启动文件夹里面 5、这样就完…...

Java-HashMap中put()方法是如何实现的,内含详细流程图
文章目录 Java中的HashMap什么是HashMap?对比其他Map中put()方法HashMap中put()方法使用示例 HashMap中put()源码解析手绘流程图实现原理源码探究(JDK 1.8) 设计put()的意义总结 Java中的HashMap 什么是HashMap? HashMap是Java中…...

kaggle赛后总结
1. 宽表 2.缺失值的处理方法 最简单粗暴的就是删除,这种情况是凡是有缺失值行数很少。均值替代。缺失值的行数比较多一点儿的时候,直接删除会影响样本数量,那就均值替代,或者中位数替代等方法。还有复杂的方法,把有缺…...

基于Vue前端框架构建BI应用程序
一、什么是Vue? Vue(Vue.js)是一个轻量级、高性能、可组件化的MVVM库。简而言之,是一个构建数据驱动的web界面的渐进式框架。它采用MVVM思想,通过数据双向绑定实现数据的动态渲染,同时也支持组件化的开发方…...

【文心一言】学习笔记
学习资料 《听说文心一言App霸榜了,那必须来一波全方位实测了》 情感陪伴:文心一言 App 可以充当用户的情感树洞,提供知心姐姐、【暖男】等角色扮演,为用户提供情绪疏导、情感分析、约会建议等服务。 1. 模型属性 【提示词工具…...

Xilinx UltraScale架构之可配置逻辑块CLB
目录 一、概览 二、UltraScale架构 2.1 UltraScale/UltraScale特点 2.2 与7系列CLB差异 三、 CLB结构 3.1 LUT 3.2 FF 3.3 多路选择器Multiplexers 3.4 进位链Carry Chain 四、应用 4.1 分布式RAM 4.2 移位寄存器 4.3 进位链Carry Chain 五、参考资料 一、概览 二…...

springboot web开发整合Freemarker 模板引擎
目录 Freemarker添加依赖配置文件ymlcontrollerhtml Freemarker 简介: FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具…...
Python 连接 SQL 数据库 -pyodbc
文章目录 使用 pyodbc 模块从 Python 代码连接到 SQL 数据库配置用于 pyodbc Python 开发的开发环境创建用于 pyodbc Python 开发的 SQL 数据库使用 pyodbc 连接到 SQL连接和查询数据 推荐阅读 在 Windows、Linux 或 macOS 上使用 Python 连接到 SQL 数据库,有几个可…...

Vue框架--Vue中的数据代理
下面,我们一起来说以下Vue中的数据代理。 1.Object.defineProperty()方法回顾 * Object.defineProperty()方法基本配置项 * value:指定设置对象内容的属性值 * enumerable:true, //控制属性是否可以枚举(也就是是否可以被遍历),默认值是false * writable:true, //控制属性是…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...