ArkTS中的自定义构建函数、Tab栏和组件状态共享

news2024/12/25 23:54:09

一、自定义构建函数

1.构建函数 @Builder

1.1 介绍

文档地址:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5?catalogVersion=V5

概念:ArkUI提供了一种轻量的UI元素复用机制@Builder,可以将重复使用的UI元素抽象成一个方法。在builder里调用。

1.2 定义的位置

组件内定义
@Builder  MyBuilderFcuntion(){
    
}

//调用
this.MyBuilderFcuntion()
全局定义
@Builder function  MyBuilderFcuntion(){
    
}

//调用
MyBuilderFcuntion()
案例

在这里插入图片描述

鸿蒙页面布局,此处我们会用到栅格布局:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-layout-development-grid-layout-V5

待实现的页面结构
@Entry
@Component
struct BuilderDemo1Page {

  build() {
    Column(){ //垂直方向布局
      //columns:分为几列,columns默认值为12
      //gutter:设置子元素在水平和垂直方向的间距。
      GridRow({columns:3,gutter:15}){
        GridCol(){
          Column(){
            Row(){
              Text('评价(200+)')
                .layoutWeight(1)
                //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
            }
            Row(){

            }
            .height(100)
          }
          .backgroundColor('#fff')
          .borderRadius(12)
          .padding(10)
        }

        GridCol(){
          Column(){
            Row(){
              Text('推荐')
                .layoutWeight(1)
                  //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
            }
            Row(){

            }
            .height(100)
          }
          .backgroundColor('#fff')
          .borderRadius(12)
          .padding(10)
        }

        GridCol(){
          Column(){
            Row(){
              Text('体验')
                .layoutWeight(1)
                  //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
            }
            Row(){

            }
            .height(100)
          }
          .backgroundColor('#fff')
          .borderRadius(12)
          .padding(10)
        }

      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f5f5')
    .padding(15)
  }
}
使用@Builder提取UI结构
@Entry
@Component
struct BuilderDemo1Page {

  @Builder
  MyBuilder(){
    Row(){
      Text('查看更多')
      Image($r('app.media.chevron_right'))
        .width(16)
        .aspectRatio(1)
    }
  }

  build() {
    Column(){ //垂直方向布局
      //columns:分为几列,columns默认值为12
      //gutter:设置子元素在水平和垂直方向的间距。
      GridRow({columns:2,gutter:15}){
        GridCol({span:2}){  //span:将几个合并成一个
          Column(){
            Row(){
              Text('评价(200+)')
                .layoutWeight(1)
                //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
              // 查看更多
              this.MyBuilder()
            }
            Row(){

            }
            .height(100)
          }
          .backgroundColor('#fff')
          .borderRadius(12)
          .padding(10)
        }

        GridCol(){
          Column(){
            Row(){
              Text('推荐')
                .layoutWeight(1)
                  //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
              // 查看更多
              this.MyBuilder()
            }
            Row(){

            }
            .height(100)
          }
          .backgroundColor('#fff')
          .borderRadius(12)
          .padding(10)
        }

        GridCol(){
          Column(){
            Row(){
              Text('体验')
                .layoutWeight(1)
                  //.fontWeight(FontWeight.Bold)
                .fontWeight(600)

              // 查看更多
              this.MyBuilder()
            }
            Row(){

            }
            .height(100)
          }
          .backgroundColor('#fff')
          .borderRadius(12)
          .padding(10)
        }

      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f5f5')
    .padding(15)
  }
}
小结

遇到非遍历情况下,一个组件分散着相同的ui结构,可以使用@Builder加上更轻量级的GridRow和GirdCol栅格布局

1.3 参数传递

场景:构建不同的UI

@Builder  MyBuilderFcuntion(title:string){
    
}

//调用
this.MyBuilderFcuntion('Title')

在这里插入图片描述

//两个位置变动
@Builder
MyBuilder(title:string){
    Row(){
        Text(title)
        Image($r('app.media.chevron_right'))
            .width(16)
            .aspectRatio(1)
    }
}
// 查看更多
this.MyBuilder('好频率98%')
this.MyBuilder('查看全部')
this.MyBuilder('4条测评')

1.4 引用传递

场景:当传递的数据更新,需要更新ui

需求:

点击按钮后,模拟加载好评率数据

在这里插入图片描述

import promptAction from '@ohos.promptAction';
class Params{
  title:string = ''
}
@Entry
@Component
struct BuilderDemo1Page {
  @State rate:number = 0;
  @Builder
  MyBuilder(params:Params){
    Row(){
      Text(params.title)
      Image($r('app.media.chevron_right'))
        .width(16)
        .aspectRatio(1)
    }
  }

  build() {
    Column(){ //垂直方向布局
      Button('获取数据')
        .onClick( () => {
            this.rate = 98;
            promptAction.showToast({message:this.rate.toString()})
        })

      //columns:分为几列,columns默认值为12
      //gutter:设置子元素在水平和垂直方向的间距。
      GridRow({columns:2,gutter:15}){
        GridCol({span:2}){  //span:将几个合并成一个
          Column(){
            Row(){
              Text('评价(200+)')
                .layoutWeight(1)
                //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
              // 查看更多
              this.MyBuilder({title:`好频率${this.rate}%`})
            }
            Row(){

            }
            .height(100)
          }
        }
        .backgroundColor('#fff')
        .borderRadius(12)
        .padding(10)

        GridCol(){
          Column(){
            Row(){
              Text('推荐')
                .layoutWeight(1)
                  //.fontWeight(FontWeight.Bold)
                .fontWeight(600)
              // 查看更多
              this.MyBuilder({title:'查看全部'})
            }
            Row(){

            }
            .height(100)
          }
        }
        .backgroundColor('#fff')
        .borderRadius(12)
        .padding(10)

        GridCol(){
          Column(){
            Row(){
              Text('体验')
                .layoutWeight(1)
                  //.fontWeight(FontWeight.Bold)
                .fontWeight(600)

              // 查看更多
              this.MyBuilder({title:'4条测评'})
            }
            Row(){

            }
            .height(100)
          }
        }
        .backgroundColor('#fff')
        .borderRadius(12)
        .padding(10)

      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f5f5')
    .padding(15)
  }
}

使用Builder复用逻辑的时候,支持参数可以更灵活渲染UI

参数可以使用状态数据,不过建议通过对象的方式传递@Builder

2.构建函数 @BuilderParam

@BuilderParam该装饰器用于声明任意UI描述一个元素,类似于slot占位符

前置知识:
组件属性初始化
	1.定义组件声明属性: title:string
	2.使用组件的初始化属性:Comp({title:string})
  • 尾随闭包初始化组件
    • 组件内有且仅有一个@BuilderParam装饰器的属性
  • 参数初始化组件
    • 组件内有多个@BuilderParam装饰器属性

2.1 尾随闭包初始化组件

需求:

  • 标题文件和更多文件通过属性传入
  • 内容结构需要传入

在这里插入图片描述

@Entry
@Component
struct BuilderParamPage {

  build() {
    Column(){
      GridRow({columns:2,gutter:15}){
        GridCol({span:2}){
          PanelComp({title:'评价(200+)',more:'好评率98%'});
        }
        GridCol(){
          PanelComp({title:'推荐',more:'查看全部'}){
            Text('推荐内容')
          };
        }
        GridCol(){
          PanelComp({title:'体验',more:'4 条测评'}){
            Text('体验内容')
          };
        }
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f5f5')
    .padding(15)
  }
}

@Component
struct PanelComp {
  title:string = ''
  more:string = ''

  @Builder
  DefaultPanelContent(){
    Text('默认内容')
  }

  @BuilderParam
  panelContent: () => void = this.DefaultPanelContent

  build() {
    Column(){
      Row(){
        Text(this.title)
          .layoutWeight(1)
          .fontWeight(600)
        Row(){
          Text(this.more)
            .fontSize(14)
            .fontColor('#666')
          Image($r('app.media.chevron_right'))
            .width(16)
            .aspectRatio(1)
            .fillColor('#666')
        }
      }
      Row(){
        this.panelContent();
      }
      .height(100)
    }
    .backgroundColor('#fff')
    .padding(10)
    .borderRadius(12)

  }
}

2.2 参数初始化组件 (具名插槽)

需求:

​ 需要传入内容结构和底部结构

在这里插入图片描述

@Entry
@Component
struct BuilderParam2Page {

  @Builder
  ContentBuilderA(){
    Text('评论内容1111')
  }
  @Builder
  ContentBuilderB(){
    Text('评论底部')
  }
  build() {
    Column(){
      GridRow({columns:2,gutter:15}){
        GridCol({span:2}){
          PanelComp2({
            title:'评价(2000+)',
            more:'好评率98%',
            panelContent: this.ContentBuilderA,
            panelFooter:this.ContentBuilderB
          })
        }
      }
    }
    .width('100%')
    .height('100%')
    .padding(15)
    .backgroundColor('#f5f5f5')
  }
}

@Component
struct PanelComp2 {
  title:string = '';
  more:string = '';
  @Builder
  DefaultPanelContent(){
    Text('默认内容')
  }
  @BuilderParam
  panelContent: () => void = this.DefaultPanelContent
  @BuilderParam
  panelFooter: () => void = this.DefaultPanelContent

  build() {
    Column(){
      Row(){
        Text(this.title)
          .layoutWeight(1)
          .fontWeight(600)
          .fontSize(14)
          .fontColor('#666')
        Row(){
          Text(this.more)
          Image($r('app.media.chevron_right'))
            .width(16)
            .aspectRatio(1)
            .fillColor('#666')
        }
      }
      Row(){
        this.panelContent()
      }
      .height(100)
      Row(){
        this.panelFooter()
      }
      .height(100)
    }
    .backgroundColor('#fff')
    .padding(10)
    .borderRadius(16)


  }
}

3.总结

  • 当子组件使用一个@BuilderParam的时候,使用组件的时候尾随 {},插入UI结构
  • 当子组件有多个@BuilderParam的时候,使用组件的时候Comp({xxx:xxxxx})传入
  • 子组件本身提供一个默认的@Builder函数作为@BuilderParam备用函数,当作准用内容使用(默认内容)

4.系统组件自定义UI

在一些系统组件中,根据配置无法达到预期的UI,就可以使用@Builder构建函数自定义UI,前提是该组件要支持自定义UI

Tabs:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-navigation-tabs-V5

4.1 基本Tab结构

@Entry
@Component
struct TabsPage {

  build() {
    Column(){
      //barPosition:控制显示的位置
      Tabs({barPosition:BarPosition.End}){
        TabContent(){
          Text('首页')
        }.tabBar('首页')
        TabContent(){
          Text('项目')
        }
        .tabBar('项目')
        TabContent(){
          Text('面试')
        }.tabBar('面试')
        TabContent() {
          Text('我的')
        }.tabBar('我的')
      }
    }
    .width('100%')
    .height('100%')
  }
}

4.2 自定义Tab结构

在这里插入图片描述

import promptAction from '@ohos.promptAction'

@Entry
@Component
struct TabsPage {
  @State activeIndex:number = 0; //默认激活的是第一个索引
  //定义个对象数组,用来存储图标相关信息
  toolBarItems:ToolBarItem[] = [
    {defaultIcon:$r('app.media.home'),activeIcon:$r('app.media.home_select'),label:'首页'},
    {defaultIcon:$r('app.media.project'),activeIcon:$r('app.media.project_select'),label:'项目'},
    {defaultIcon:$r('app.media.interview'),activeIcon:$r('app.media.interview_select'),label:'面试'},
    {defaultIcon:$r('app.media.mine'),activeIcon:$r('app.media.mine_select'),label:'我的'},
  ]
  @Builder
  TabBarBuilder(item:ToolBarItem,index:number){
    Column(){
      Image(this.activeIndex === index?item.activeIcon:item.defaultIcon)
        .width(24)
        .aspectRatio(1)
      Text(item.label)
        .lineHeight(12)
        .margin({top:4})
        .fontColor(this.activeIndex === index?'#000':'#aaa')
    }
  }
  build() {
    Column(){
      //barPosition:控制显示的位置
      Tabs({barPosition:BarPosition.End}){
        //循环遍历
        ForEach(this.toolBarItems,(item:ToolBarItem,index:number)=>{
          TabContent(){
            Text(item.label)
          }.tabBar(this.TabBarBuilder(item,index))

        })

      }
      .onChange( (index:number) => {
        //获取到点击的索引
        // promptAction.showToast({message:index.toString()})
        this.activeIndex = index;//获取到当前激活的索引
      })
    }
    .width('100%')
    .height('100%')
  }
}

//类:描述ToolBar
class ToolBarItem{
  defaultIcon:string | Resource = '' //默认图标
  activeIcon:string | Resource = ''  //激活图标
  label: string = ''                //文字
}

二、组件状态共享

1.父子单向

@Prop 装饰的变量可以和父组件建立单向的同步关系

@Prop装饰的变量是可变的,但是变化不同同步回到父组件

@Entry
@Component
struct PropPage {
  @State money:number = 0;
  build() {
    Column({space:20}){
      Text('父组件:' + this.money)
        .fontSize(20)
        .onClick(() => {
          this.money++
        })

      //引入子组件
      Child1({money: this.money});
    }
  }
}

@Component
struct Child1 {
  //@Prop是父子单向
  @Prop money:number;
  // @Prop money:number = 10;
  build() {
    Text('子组件:' + this.money)
      .fontSize(20)
      .onClick(() => {
        this.money++
      })
  }
}

支持的类型:

  • string
  • number
  • boolean
  • enum

子组件可以修改Prop的数据值,父组件更新后覆盖子组件Prop的数据

子组件可以有初始化的默认值,注意:目前的编译器是已经修复bug,不会报错

2.父子双向

子组件中用@Link装饰的变量与父组件中对应的数据建立双向数据绑定

2.1 简单类型

string、number、boolean、enum

@Entry
@Component
struct Link1Page {
  @State money:number = 0;
  build() {
    Column({space:20}){
      Text('父组件:' + this.money)
        .fontSize(20)
        .onClick(() => {
          this.money++
        })

      //引入子组件
      Child2({money: this.money});
    }
  }
}

@Component
struct Child2 {
  //@Link父子双向
  @Link money:number;
  build() {
    Text('子组件:' + this.money)
      .fontSize(20)
      .onClick(() => {
        this.money++
      })
  }
}

2.2 复杂类型

object、class

@Entry
@Component
struct Link2Page {
  @State person:Person = {name:'kunkun',age:26};
  build() {
    Column({space:20}){
      Text(`父组件: + ${this.person.name},今年${this.person.age}岁了`)
        .fontSize(20)
        .onClick(() => {
          this.person.age++
        })

      //引入子组件
      Child3({person:$person});
      // Child3({person:this.person});
    }
  }
}

@Component
struct Child3 {
  //@Link父子双向
  @Link person:Person;
  build() {
    Text(`子组件: + ${this.person.name},今年${this.person.age}岁了`)
      .fontSize(20)
      .onClick(() => {
        this.person.age++
      })
  }
}
//自定义类型
class Person{
  name:string = ''
  age:number = 0
}

父组件传值的时候,需要this. 改写成$

子组件@Link装饰数据

3.后代组件

@Provideconsume ,应用于与后代组件的双向数据同步,应用于状态的数据的多个层级之间传递场景

3.1 通过相同的变量名绑定

必须保证变量名是相同

@Entry
@Component
struct ProvidePage {
  @Provide money:number = 0;

  build() {
    Column({space:25}){
      Text('父组件:' + this.money)
        .onClick(() => {
          this.money++
        })
      Child4()
    }
  }
}

@Component
struct Child4 {
  //不可以给初始值
  @Consume money:number;
  build() {
    Text('子组件:' + this.money)
      .onClick(() => {
        this.money++
      })
  }
}

Tip ⏲

  • Object、class、string、number、boolean、enum类型都支持
  • 通过相同的变量名绑定@Provide@Consume的变量名一致

3.2 状态监听

如果开发者需要关注某个变量的值是否发生变化,可以使用@watch为状态变量设置回调函数

@State 、@Prop 和@Link等装饰器在@Watch装饰之前

import promptAction from '@ohos.promptAction'

@Entry
@Component
struct WatchPage {
  @State activeIndex:number = 0;

  build() {
    Column(){

      Button('按钮1')
        .onClick(()=>{
          this.activeIndex = 1;
          promptAction.showToast({message:this.activeIndex.toString()})
        })
      Button('按钮2')
        .onClick(()=>{
          this.activeIndex = 2;
          promptAction.showToast({message:this.activeIndex.toString()})
        })


      Child5({activeIndex:this.activeIndex});
    }
  }
}


@Component
struct Child5 {
  @Prop @Watch('onActionIndex') activeIndex:number = 0

  onActionIndex(){
    promptAction.showToast({message:'监听到了变化 -->' + this.activeIndex})
  }

  build() {
    Text('Child5---->'  + this.activeIndex)
  }
}

TIP:

在第一次初始化的时候,@Watch装饰器的方法是不会被调用的

3.2 @Observed 与@ObjectLink

之前我们通过 赋值的方式 修改嵌套对象或对象数组这类复杂数据来更新UI的

使用步骤:

  • 类class数据模拟需要定义通过构造函数,使用@Observed修改这个类
  • 初始化数据:需要通过初始化构造方式添加
  • 通过@ObjectLink关联对象,可以直接修改被关联对象来更新UI

在这里插入图片描述

//创建接口
interface ReplyItemInterface{
  id?:number
  avatar?:string | Resource
  author?:string
  content?:string
  time?:string
  area?:string
  linkNum?:number
  likeFlag?:boolean
}
@Observed
export class ReplyItem{
  id?:number
  avatar?:string | Resource
  author?:string
  content?:string
  time?:string
  area?:string
  linkNum?:number
  likeFlag?:boolean

  //构造函数中要求使用接口类型
  constructor(item:ReplyItemInterface) {
    this.id = item.id
    this.avatar = item.avatar
    this.author = item.author
    this.content = item.content
    this.time = item.time
    this.area = item.area
    this.linkNum = item.linkNum
    this.likeFlag = item.likeFlag
  }
}
//创建对象数组
export const replyList:ReplyItem[] = [
  new ReplyItem({id:1,avatar:$r('app.media.kun'),author:'金庸',content:'倚天屠龙记',time:'16:54',area:'武汉',linkNum:30,likeFlag:true}),
  new ReplyItem({id:1,avatar:$r('app.media.kun'),author:'金庸',content:'倚天屠龙记',time:'16:54',area:'武汉',linkNum:30,likeFlag:true}),
  new ReplyItem({id:1,avatar:$r('app.media.kun'),author:'金庸',content:'倚天屠龙记',time:'16:54',area:'武汉',linkNum:30,likeFlag:true})
]
import {ReplyItem,replyList} from '../model/common'
import promptAction from '@ohos.promptAction'

@Entry
@Component
struct ZhihuPage {
  @State content:string = ''
  //评论对象数组
  @State replyList:ReplyItem[] = replyList
  //回复消息
  onReply(){
    const reply:ReplyItem = new ReplyItem({id:1,avatar:$r('app.media.kun'),author:'蔡徐坤',content:this.content,time:'16:54',area:'武汉',linkNum:30,likeFlag:true})
    //添加到对象数组中
    // this.replyList.push(reply) //添加到数组的最后一个
    this.replyList.unshift(reply) //添加到对象数组中的第一个
    this.content = ''
    promptAction.showToast({message:'回复成功'})
  }
  build() {
    Column(){
      TextInput({placeholder:'回复'})
        .layoutWeight(1)
        .onChange((value:string) => {
          this.content = value; //获取到输入框中输入的值
        })
      
      ForEach(this.replyList,(item:ReplyItem) => {
        ReplyComp({item:item})
      })
      Button('发布')
        .onClick(()=> {
          this.onReply();//发布消息
        })
    }
  }
}

@Component
struct ReplyComp {
  @ObjectLink item:ReplyItem
  build() {
    Column(){
      Image(this.item.avatar)
        .width(32)
        .aspectRatio(1)
        .borderRadius(16)
      Column(){
        Text(this.item.author)
          .fontSize(15)
          .fontWeight(100)
          .margin({top:5})
        Text(this.item.content)
          .margin({top:5})
          .fontColor('blue')
          .lineHeight(20)
      }
    }
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二维、三维情况下的锚点优选方法

多锚点定位时,锚点的选择对定位精度有重要影响。下面介绍基于误差最小化的锚点选择的相应公式和MATLAB代码示例,并进行详细分析 文章目录 方法描述代码MATLAB代码示例代码运行结果 总结 方法描述 选择能够最小化定位误差的锚点组合。通过计算锚点位置与…

CCF ChinaOSC |「开源科学计算与系统建模openSCS专题分论坛」11月9日与您相约深圳

2024年11月9日至10日,以“湾区聚力 开源启智”为主题的2024年中国计算机学会中国开源大会(CCF ChinaOSC)将在深圳召开。大会将汇聚国内外学术界、顶尖科技企业、科研机构及开源社区的精英力量,共同探索人工智能技术和人类智慧的无…

力扣102:二叉树的层次遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]示例 2: 输入&a…

数学建模模型算法-Python实现

一、评价决策类 1、层次分析法(AHP) 层次分析法用来评价或选择一个更好更优的决策或方案 通过找到可以衡量其好坏的指标,进而衡量指标,再形成评价体系 归一化处理 让指标在同一数量级,且保证在同一指标下其差距保持…

linux-vlan(1)

# VLAN # 1.topo # 2.创建命名空间 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns1-veth0 type veth peer name ns21-veth0 ip link add ns3-veth0 type veth peer name ns23-veth0 # 4.veth设备放入命名空间,启动接口 ip link set n…

spring cloud 入门笔记1(RestTemplate,Consul)

最大感受: spring cloud无非是将spring boot中的各个工作模块拆分成独立的小spring boot,各个模块之间,不再是通过导包什么的,调用而是通过网路进行各个模块之间的调用 工具一:RestTemplate 在Java代码中发送HTTP请…

FlinkSql读取kafka数据流的方法(scala)

我的scala版本为2.12 <scala.binary.version>2.12</scala.binary.version> 我的Flink版本为1.13.6 <flink.version>1.13.6</flink.version> FlinkSql读取kafka数据流需要如下依赖&#xff1a; <dependency><groupId>org.apache.flink&…

Docker 安装Immich教程

Immich 是一个开源的自托管照片和视频管理平台,专为帮助用户存储、管理、和分享个人媒体库而设计。Immich 的目标是提供一个类似 Google Photos 的替代方案,但不依赖于第三方服务,用户可以完全控制自己的数据。 本章教程,记录如何用Docker部署安装Immich,使用的操作系统的…

【CICD】CICD 持续集成与持续交付在测试中的应用

一、什么是CICD&#xff1f; CI/CD 是指持续集成&#xff08;Continuous Integration&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;或持续交付&#xff08;Continuous Delivery&#xff09; 1.1 持续集成&#xff08;Continuous Integration&#xf…

交友问题 | 动态规划

描述 如果有n个人&#xff0c;每个人都可以保持单身或与其他人结成一对。每个人只能找一个对象。求总共有多少种保持单身或结对的方式。用动态规划求解。 输入 输入第一行t表示测试用例的数量 对于每一个测试用例, 输入一个整数n表示人数1<n<18 输出 针对每个测试用…

Web开发:ABP框架6——appsetting.json的读取以及实例的注入

目录 一、模块配置服务 二、配置服务的编写&#xff08;配置ORM&#xff09; 三、高层代码的运用&#xff08;ORM实例查询 & 获取字符串&#xff09; 一、模块配置服务 BookStoreHttpApiHostModule 二、配置服务的编写&#xff08;配置ORM&#xff09; (以freesql为例子…

tomcat启动运行乱码,解决方案

tomcat启动运行乱码,解决方案 不要修改系统设置;我们是要让tomcat兼容我们系统,不是让系统兼容tomcat。不要修改系统设置;我们是要让tomcat兼容我们系统,不是让系统兼容tomcat。不要修改系统设置;我们是要让tomcat兼容我们系统,不是让系统兼容tomcat。解决方案 找到你的…

UE5材质篇 3 MaterialFunction

这个可以避免一部分的蜘蛛网&#xff0c;这样就用的时候很多蜘蛛网缩小成为一个节点 https://dev.epicgames.com/documentation/en-us/unreal-engine/creating-and-using-material-functions-in-unreal-engine 首先创建一个&#xff0c;这里这个名字他就是函数名&#xff0c;后…

linux命令详解,文件系统权限相关

文件系统权限相关 linux系统中一切都是文件 查看权限 Is -la /etc/passwd更改文件所有者 chown root file修改文件权限 sudo chmod urwx,grw,o-r file sudo chmod ux,gtw,o-r file chmod 400 <file>一、Linux系统中一切都是文件 在linux系统中&#xff0c;几乎所有的…

基本数据类型和包装类型的区别、缓存池、自动拆箱装箱(面试题)

目录 1. 八种基本类型及对应包装类型 2. 基本类型和包装类型 区别 3. 自动拆箱装箱 3.1 自动装箱 3.2 自动拆箱 3.3 缓存池 4. 高频面试案例分析 1. 八种基本类型及对应包装类型 基本数据类型类型描述范围&#xff08;指数形式&#xff09;位数包装类型byte整型&#x…

如何在Microsoft Edge中删除已保存的网站密码

目录 前言1. 如何进入Edge的密码管理界面1.1 打开Microsoft Edge的设置菜单1.2 进入个人资料设置1.3 进入密码管理 2. 在Edge中查看和删除已保存的密码2.1 查找需要删除的密码2.2 检查密码安全性2.3 删除特定网站的密码 3. 提升Edge密码管理的安全性3.1 启用Edge的多重身份验证…

Spring Boot框架:电商开发的新趋势

5 系统实现 系统实现部分就是将系统分析&#xff0c;系统设计部分的内容通过编码进行功能实现&#xff0c;以一个实际应用系统的形式展示系统分析与系统设计的结果。前面提到的系统分析&#xff0c;系统设计最主要还是进行功能&#xff0c;系统操作逻辑的设计&#xff0c;也包括…

后端:Aop 面向切面编程

文章目录 1. Aop 初步学习面向切面编程&#xff0c;EnableAspectJAutoProxy2. AOP的核心概念3. 前置通知&#xff08;Before&#xff09;4. 后置通知&#xff08;After&#xff09;5. 返回通知&#xff08;AfterReturning&#xff09;6. 异常通知&#xff08;AfterThrowing&…

三周精通FastAPI:41 部署:FastAPI版本和HTTPS概念

官方文档&#xff1a;https://fastapi.tiangolo.com/zh/deployment/versions/ 关于 FastAPI 版本 FastAPI 已在许多应用程序和系统的生产环境中使用。 并且测试覆盖率保持在100%。 但其开发进度仍在快速推进。 经常添加新功能&#xff0c;定期修复错误&#xff0c;并且代码仍…

Pinpoint(APM)进阶--Pinot指标采集(System Metric/Inspector)

接上文 Pinpoint使用Pinot进行指标数据存储&#xff0c;Pinot流摄入需要Kafka 本文详解Kafka和Pinot的安装部署&#xff0c;以及Pinpoint的指标采集 Pinot 简介 Apache Pinot是一个实时分布式OLAP数据存储&#xff0c;专为低延迟、高吞吐量分析而构建&#xff0c;非常适合面…