一、构建自定义组件Header用来封装页头
1.1首先我们在编译器中先创建一个ArkTS文件,命名为Header
如下所示:
@Component
struct Header {
build() {
}
}
1.2创建一个ArkTS文件命名为ImagePage7
@Entry
@Component
struct ImagePage7 {
build() {
}
}
1.3设置Row布局,添加image,利用space设置间距,添加blank组件,填满剩余空间。
build() {
Row({space:10}){
Image($r('app.media.fanhuijiantou'))
.width(30)
Text(this.title)
.fontSize(30)
.fontWeight(FontWeight.Bold) //字体加粗
Blank() //占满剩余空间
Image($r('app.media.shuaxinanniu'))
.width(30)
}
.width('100%')
.padding(20)
}
1.4定义一个title变量标题,传入数据。
struct Header {
title:string
build() {
Row({space:10}){
Image($r('app.media.fanhuijiantou'))
.width(30)
Text(this.title)
.fontSize(30)
.fontWeight(FontWeight.Bold) //字体加粗
Blank() //占满剩余空间
Image($r('app.media.shuaxinanniu'))
.width(30)
}
.width('100%')
.padding(20)
}
}
1.5我们对自定义Header组件进行导出工作
export default struct Header {
title:string
build() {
Row({space:10}){
Image($r('app.media.fanhuijiantou'))
.width(30)
Text(this.title)
.fontSize(30)
.fontWeight(FontWeight.Bold) //字体加粗
Blank() //占满剩余空间
Image($r('app.media.shuaxinanniu'))
.width(30)
}
.width('100%')
.padding(20)
}
}
1.6我们在ImagePage7里面设置column容器
struct Image7
struct Image7Page {
build() {
Row(){
Column({space:10}) {
Header({title:'商品列表'})
Row(){
Column({space:10}) {
Header({title:'商品列表'})
导包:
//import导入Header
//加上default Header就不能再加上{}
import Header from '../components/Header'
Export对外有一个访问接口,在header的导出方法中添加default则不用加上{}。
@Component
export default struct Header {
title:string
1.7添加属性,设置宽度和高度
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)
二、循环渲染
2.1定义一个ImageItem类,实例化商品名称,图片,价格,折扣。
//声明一个类ImageItem类
class ImageItem{
name:string
image:ResourceStr
price:number
discount:number
//修改里面的值
setName(name:string){
// this.name=this.name+name
this.name=name
}
getName(){
return this.name
}
2.2定义构造函数传参
//定义一个构造函数
constructor(name:string,image:ResourceStr, price:number, discount?:number) {
//?:非必选,设置可选参数
this.name=name
this.image=image
this.price=price
this.discount=discount
}
2.3定义数组
struct Image7Page {
//定义数组
private list:Array<ImageItem>=[
new ImageItem('华为Mate60',$r('app.media.huaweiMate60'),6999,500),
new ImageItem('华为book',$r('app.media.huaweiBook'),13999),
new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
new ImageItem('Mate X5',$r('app.media.matex5'),12999),
new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
new ImageItem('Mate X5',$r('app.media.matex5'),12999)
]
2.4创建row组件传子组件image
build() {
Row(){
Column({space:10}){
Header({title:'商品列表'})
Row(){
Image(item.image)
.width(100)
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
2.5用foreach进行渲染
ForEach(this.list,(item:ImageItem)=>{
Row(){
Image(item.image)
.width(100)
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Text(`原价:¥ ${item.price}`)
三、条件渲染
3.1在column中写入text组件
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Text(`原价:¥ ${item.price}`)
Text(`折扣价:¥ ${item.price-item.discount}`)
Text(`补贴:¥ ${item.discount}`)
3.2用if else判断语句
if (item.discount){
Text(`原价:¥${item.price}`)
// .fontSize(18)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥${item.price - item.discount}`)
.priceText()
Text(`补贴:¥${item.discount}`)
.priceText()
}else {
Text('原价:¥'+item.price)
.priceText()
// .fontSize(16)
// .fontColor('#F36')
}
}
四、List组件
4.1添加list
List( {space:10}){
ForEach(this.list,(item:ImageItem)=>{
if (item.discount){
Text(`原价:¥ ${item.price}`)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥ ${item.price-item.discount}`)
.fontSize(16)
.fontColor('#F36')
Text(`补贴:¥ ${item.discount}`)
}else{
Text('原价:¥'+item.price)
.fontSize(16)
.fontColor('#F36')
}
}
4.2使用list子组件listitem
List( {space:10}){
ForEach(this.list,(item:ImageItem)=>{
ListItem(){
Row(){
Image(item.image)
.width(100)
Column(){
//标题名字固定
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
//用if渲染
if (item.discount){
Text(`原价:¥ ${item.price}`)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥ ${item.price-item.discount}`)
.fontSize(16)
.fontColor('#F36')
Text(`补贴:¥ ${item.discount}`)
.fontSize(16)
.fontColor('#F36')
}else{
Text('原价:¥'+item.price)
.fontSize(16)
.fontColor('#F36')
}
}
4.3设置键值,设置为一标识
ForEach(this.list,(item:ImageItem)=>{ //重复渲染
ListItem(){
itemCardToal(item)
}
},(item:ImageItem) => item.name)//name是唯一标识
4.4进行美化
build() {
Row(){
Column({space:10}){
Header({title:'商品列表'})
List( {space:10}){
ForEach(this.list,(item:ImageItem)=>{
ListItem(){
Row(){
Image(item.image)
.width(100)
Column(){
//标题名字固定
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
//用if渲染
if (item.discount){
Text(`原价:¥ ${item.price}`)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥ ${item.price-item.discount}`)
.fontSize(16)
.fontColor('#F36')
Text(`补贴:¥ ${item.discount}`)
.fontSize(16)
.fontColor('#F36')
}else{
Text('原价:¥'+item.price)
.fontSize(16)
.fontColor('#F36')
}
}
.height('100%')
.alignItems(HorizontalAlign.Start)
}//设置圆角边框大小,背景颜色
.height(120)
.width('100%')
.borderRadius(20)
.backgroundColor('#FFF')
.padding(10)
}
},(item:ImageItem)=>item.name) //键值生成规则 重复渲染 设置唯一标识
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)
}
}
五、自定义构建函数
5.1创建自定义函数itemCard
@Builder ItemCard(item:ImageItem){
Row(){
Image(item.image)
.width(100)
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
if (item.discount){
Text(`原价:¥ ${item.price}`)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥ ${item.price-item.discount}`)
.fontSize(16)
.fontColor('#F36')
Text(`补贴:¥ ${item.discount}`)
.fontSize(16)
.fontColor('#F36')
}else{
Text('原价:¥'+item.price)
.fontSize(16)
.fontColor('#F36')
}
}
.height('100%')
.alignItems(HorizontalAlign.Start)
}//设置row的宽度和高度,以及圆角边框大小,背景颜色
.height(120)
.width('100%')
.borderRadius(20)
.backgroundColor('#FFF')
.padding(10)
5.2再回到listltem里面直接调用itemcard
List( {space:10}){
ForEach(this.list,(item:ImageItem)=>{
ListItem(){
// 直接调用自定义函数ItemCard
this.ItemCard(item)
六、@Style装饰器
6.1创建fillScreen进行封装
@Styles function fillScreen1(){
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)
}
6.2对row调用
@Builder function itemCardToal(item:ImageItem){
Row(){
Image(item.image)
.width(100)
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
if (item.discount){
Text(`原价:¥${item.price}`)
// .fontSize(18)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥${item.price - item.discount}`)
.priceText()
Text(`补贴:¥${item.discount}`)
.priceText()
}else {
Text('原价:¥'+item.price)
.priceText()
// .fontSize(16)
// .fontColor('#F36')
}
}.alignItems(HorizontalAlign.Start) //设置水平居中左对齐
.fillScreen()
}//设置row的宽度高度和圆角边框的大小和背景颜色
.fillScreen()
}
如上所示,对column也就进行调用
七、@Extend装饰器
7.1定义pricetext写入字体大小
@Extend(Text)function priceText(){
.fontSize(16)
.fontColor('#F36')
}
7.2调用扩展样式
@Builder function ItemCardTotal(item:ImageItem){
Row(){
Image(item.image)
.width(100)
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
if (item.discount){
Text(`原价:¥ ${item.price}`)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥ ${item.price-item.discount}`)
.priceText()
Text(`补贴:¥ ${item.discount}`)
.priceText()
}else{
Text('原价:¥'+item.price)
.priceText()
}
}.alignItems(HorizontalAlign.Start)
.fillScreen1()
}
.fillScreen()
}
八、整体代码如下:
//import导入Header
//加上default Header就不能再加上{}
import Header from '../components/Header'
//声明一个类ImageItem类
class ImageItem{
name:string
image:ResourceStr
price:number
discount:number
//修改里面的值
setName(name:string){
// this.name=this.name+name
this.name=name
}
getName(){
return this.name
}
//定义一个构造函数
constructor(name:string,image:ResourceStr, price:number, discount?:number) {
//?:非必选,设置可选参数
this.name=name
this.image=image
this.price=price
this.discount=discount
}
}
//全局自定义构建函数需要加funcation函数,所以build里就不需要this来进行调用了
@Builder function itemCardToal(item:ImageItem){
Row(){
Image(item.image)
.width(100)
Column(){
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
if (item.discount){
Text(`原价:¥${item.price}`)
// .fontSize(18)
.fontColor('#ccc')
.decoration({type:TextDecorationType.LineThrough})
Text(`折扣价:¥${item.price - item.discount}`)
.priceText()
Text(`补贴:¥${item.discount}`)
.priceText()
}else {
Text('原价:¥'+item.price)
.priceText()
// .fontSize(16)
// .fontColor('#F36')
}
}.alignItems(HorizontalAlign.Start) //设置水平居中左对齐
.fillScreen()
}//设置row的宽度高度和圆角边框的大小和背景颜色
.fillScreen()
}
@Styles function fillScreen(){
.height(120)
.width('100%')
.borderRadius(20) //设置圆角
.backgroundColor('#FFF')
.padding(10)
}
@Styles function fillScreen1(){
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)
}
@Extend(Text)function priceText(){
.fontSize(16)
.fontColor('#F36')
}
@Entry
@Component
struct Image7Page {
//定义数组
private list:Array<ImageItem>=[
new ImageItem('华为Mate60',$r('app.media.huaweiMate60'),6999,500),
new ImageItem('华为book',$r('app.media.huaweiBook'),13999),
new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
new ImageItem('Mate X5',$r('app.media.matex5'),12999),
new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
new ImageItem('Mate X5',$r('app.media.matex5'),12999)
]
//如果不传参数,直接默认值给0
test(name:string,age:number=0){
console.log('name',name,'age',age)
}
build() {
Row(){
Column({space:10}) {
Header({title:'商品列表'})
List(){
ForEach(this.list,(item:ImageItem)=>{ //重复渲染
ListItem(){
itemCardToal(item)
}
},(item:ImageItem) => item.name)//name是唯一标识
}.layoutWeight(1)
}.fillScreen1()
}
}
}