HarmonyOS鸿蒙Next中请教怎么简化这个函数?
HarmonyOS鸿蒙Next中请教怎么简化这个函数?
@Builder
MyText(name: string, tnum: MENUTYPE) {
if (tnum == MENUTYPE.ESHUCAI) {
Text(name + '(' + this.m_countShuCai + ')')
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
if (tnum == MENUTYPE.EROU) {
Text(name + '(' + this.m_countRou + ')')
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
if (tnum == MENUTYPE.EWUGU) {
Text(name + '(' + this.m_countWuGu + ')')
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
if (tnum == MENUTYPE.ETIAOLIAO) {
Text(name + '(' + this.m_countTiaoLiao + ')')
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
}
更多关于HarmonyOS鸿蒙Next中请教怎么简化这个函数?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
13 回复
根据给的demo,楼主的想法应该是想各自统计不同类别的数量。
优化方式如下:
class Tmp5 {
public name: string = '';
public count: number = 0;
}
@Component
export struct TestPage{
@State m_countShuCai: number = 0
@State m_countRou: number = 0
@State m_countWuGu: number = 0
@State m_countTiaoLiao: number = 0
@Builder
MyText(params: Tmp5) {
Text(params.name + '(' + params.count + ')')
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
build() {
Column(){
this.MyText({name: '蔬菜', count: this.m_countShuCai})
this.MyText({name: '肉', count: this.m_countRou})
this.MyText({name: '五谷', count: this.m_countWuGu})
this.MyText({name: '调料', count: this.m_countTiaoLiao})
Text('点击按钮').margin({top: 20}).onClick(() => {
this.m_countShuCai = this.m_countShuCai + 1
this.m_countRou += 1
})
}
}
}
更多关于HarmonyOS鸿蒙Next中请教怎么简化这个函数?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
的确,加了。几周不写就漏了。。。
这样穿的不是引用,界面更新不了吧
问题点:count重复太多、维护成本高。
优化点:先算出 count,再只写一份 Text 样式。
示例代码:
@Builder
MyText(name: string, tnum: MENUTYPE) {
let count: number = 0
if (tnum === MENUTYPE.ESHUCAI) {
count = this.m_countShuCai
} else if (tnum === MENUTYPE.EROU) {
count = this.m_countRou
} else if (tnum === MENUTYPE.EWUGU) {
count = this.m_countWuGu
} else if (tnum === MENUTYPE.ETIAOLIAO) {
count = this.m_countTiaoLiao
}
Text(name + '(' + count + ')')
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
m_countXXX都是@state,需要界面更新
根据提供的信息,主要做以下优化,核心优化思路:
以下是Demo示例:
// 定义菜单类型枚举 - 添加前缀避免冲突
enum FoodMenuType {
VEGETABLE = 0, // 蔬菜
MEAT = 1, // 肉类
GRAIN = 2, // 五谷
CONDIMENT = 3 // 调料
}
// 菜单项数据接口 - 添加前缀
interface FoodMenuItem {
name: string;
type: FoodMenuType;
icon: string;
}
@Entry
@Component
struct MenuDemo {
// 各类食材数量 - 使用 [@State](/user/State) 确保界面更新
[@State](/user/State) m_countVegetable: number = 5;
[@State](/user/State) m_countMeat: number = 3;
[@State](/user/State) m_countGrain: number = 8;
[@State](/user/State) m_countCondiment: number = 12;
// 菜单数据
private menuItems: FoodMenuItem[] = [
{ name: '蔬菜', type: FoodMenuType.VEGETABLE, icon: '🥬' },
{ name: '肉类', type: FoodMenuType.MEAT, icon: '🥩' },
{ name: '五谷', type: FoodMenuType.GRAIN, icon: '🌾' },
{ name: '调料', type: FoodMenuType.CONDIMENT, icon: '🧂' }
];
// ==================== 优化后的 [@Builder](/user/Builder) ====================
[@Builder](/user/Builder)
MyTextOptimized(name: string, tnum: FoodMenuType) {
Text(`${name}(${this.getCountByType(tnum)})`)
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.borderRadius(20)
}
/**
* 根据类型获取对应数量
*/
private getCountByType(type: FoodMenuType): number {
switch (type) {
case FoodMenuType.VEGETABLE:
return this.m_countVegetable;
case FoodMenuType.MEAT:
return this.m_countMeat;
case FoodMenuType.GRAIN:
return this.m_countGrain;
case FoodMenuType.CONDIMENT:
return this.m_countCondiment;
default:
return 0;
}
}
build() {
Column({ space: 20 }) {
// 标题
Text('食材分类统计')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
// 优化后的 Builder
Text('通过 this 访问状态变量')
.fontSize(14)
.fontColor('#666666')
Row({ space: 10 }) {
ForEach(this.menuItems, (item: FoodMenuItem) => {
this.MyTextOptimized(item.name, item.type)
})
}
Divider().margin({ top: 10, bottom: 10 })
// 操作按钮
Text('操作面板')
.fontSize(16)
.fontWeight(FontWeight.Medium)
Row({ space: 10 }) {
Button('蔬菜+1')
.onClick(() => { this.m_countVegetable++; })
.backgroundColor('#4CAF50')
Button('肉类+1')
.onClick(() => { this.m_countMeat++; })
.backgroundColor('#F44336')
Button('五谷+1')
.onClick(() => { this.m_countGrain++; })
.backgroundColor('#FF9800')
Button('调料+1')
.onClick(() => { this.m_countCondiment++; })
.backgroundColor('#9C27B0')
}
Row({ space: 10 }) {
Button('蔬菜-1')
.onClick(() => {
if (this.m_countVegetable > 0) this.m_countVegetable--;
})
.backgroundColor('#81C784')
Button('肉类-1')
.onClick(() => {
if (this.m_countMeat > 0) this.m_countMeat--;
})
.backgroundColor('#E57373')
Button('五谷-1')
.onClick(() => {
if (this.m_countGrain > 0) this.m_countGrain--;
})
.backgroundColor('#FFB74D')
Button('调料-1')
.onClick(() => {
if (this.m_countCondiment > 0) this.m_countCondiment--;
})
.backgroundColor('#BA68C8')
}
Button('重置所有')
.onClick(() => {
this.m_countVegetable = 5;
this.m_countMeat = 3;
this.m_countGrain = 8;
this.m_countCondiment = 12;
})
.backgroundColor('#607D8B')
.width('80%')
}
.width('100%')
.padding(20)
.backgroundColor('#F5F5F5')
}
}
整体代码重复太多了吧,只有两个地方不一样。拼接的计数字段:m_countShuCai / m_countRou /…
枚举类型:MENUTYPE.xxx
简单改一下:
@Builder
MyText(name: string, tnum: MENUTYPE) {
const count = {
[MENUTYPE.ESHUCAI]: this.m_countShuCai,
[MENUTYPE.EROU]: this.m_countRou,
[MENUTYPE.EWUGU]: this.m_countWuGu,
[MENUTYPE.ETIAOLIAO]: this.m_countTiaoLiao,
}[tnum];
count && Text(`${name}(${count})`)
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.borderRadius(20);
}
2楼说的没毛病
思路走偏了!
如果你只是想给一个Text赋值,那么只需要定义一个m_count的变量去赋值就行了。而不是定义那么多个count。
方案一(简单直接):
@Builder
MyText(name: string, tnum: MENUTYPE) {
Text(this.getDisplayText(name, tnum))
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
// 提取文本生成逻辑
private getDisplayText(name: string, tnum: MENUTYPE): string {
let count = 0;
switch (tnum) {
case MENUTYPE.ESHUCAI:
count = this.m_countShuCai;
break;
case MENUTYPE.EROU:
count = this.m_countRou;
break;
case MENUTYPE.EWUGU:
count = this.m_countWuGu;
break;
case MENUTYPE.ETIAOLIAO:
count = this.m_countTiaoLiao;
break;
}
return `${name}(${count})`;
}
方案二(映射表,更优雅):
// 定义计数映射
private countMap: Map<MENUTYPE, number> = new Map([
[MENUTYPE.ESHUCAI, this.m_countShuCai],
[MENUTYPE.EROU, this.m_countRou],
[MENUTYPE.EWUGU, this.m_countWuGu],
[MENUTYPE.ETIAOLIAO, this.m_countTiaoLiao]
]);
@Builder
MyText(name: string, tnum: MENUTYPE) {
Text(`${name}(${this.countMap.get(tnum) || 0})`)
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
方案三(样式提取,适合多处复用):
// 定义计数映射
private countMap: Map<MENUTYPE, number> = new Map([
[MENUTYPE.ESHUCAI, this.m_countShuCai],
[MENUTYPE.EROU, this.m_countRou],
[MENUTYPE.EWUGU, this.m_countWuGu],
[MENUTYPE.ETIAOLIAO, this.m_countTiaoLiao]
]);
@Builder
MyText(name: string, tnum: MENUTYPE) {
Text(`${name}(${this.countMap.get(tnum) || 0})`)
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({
left: 12,
right: 12,
top: 8,
bottom: 8
})
.borderRadius(20)
}
m_countXXX都是@state,需要界面更新
无法简化未知函数,请提供具体ArkTS代码。通常简化可通过提取公共逻辑、使用解构赋值、箭头函数或合并重复条件实现。
提取公共样式,用变量区分计数来源即可:
@Builder
MyText(name: string, tnum: MENUTYPE) {
let count = 0
switch(tnum) {
case MENUTYPE.ESHUCAI: count = this.m_countShuCai; break;
case MENUTYPE.EROU: count = this.m_countRou; break;
case MENUTYPE.EWUGU: count = this.m_countWuGu; break;
case MENUTYPE.ETIAOLIAO: count = this.m_countTiaoLiao; break;
}
Text(`${name}(${count})`)
.fontSize(16)
.fontColor('#2E7D32')
.backgroundColor('#00000000')
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#E8F5E9', 0.0], ['#C8E6C9', 1.0]]
})
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.borderRadius(20)
}
四段重复逻辑合并为一段,仅通过switch获取对应计数值。

