ArkTS自定义组件
一、定义自定义组件
使用@Component注解来进行组件的注册,以便更好的在别的文件下引用
示例:
@Component
struct MyCom{
build(){
Column(){
Text('自定义组件')
Button('点击')
}
}
}
@Entry
@Component
struct Index{
build(){
Column(){
MyCom()
MyCom()
}
}
}
二、自定义组件的属性,样式
组件内的样式不会受外界调用时候的影响,只会缩放(可能还会是直接少显示一部分),不会改变颜色,位置,方法等
所以在使用组件的时候,要给其留有充足的位置
示例:
在ets文件下建一个components文件夹用来存放自定义组件
@Preview
@Component
export struct MyCom {
@State mes: string = '这是一个自定义组件'
build() {
Column() {
Text(this.mes)
.fontSize(20)
.width(200)
.height(20)
.textAlign(TextAlign.Center)
.fontColor('#ccc')
.backgroundColor(Color.White) // 组件的背景颜色设置为白色
}
}
}
在index文件里面调用
import { MyCom } from '../components/MyCom'
@Entry
@Component
struct Index {
build() {
Column() {
MyCom()
}
.width('100%')
.backgroundColor('#BFECFF') //将整个Column设置为#BFECFF颜色,但是并没有改变组件原来的白色
.height(50)
.justifyContent(FlexAlign.Center)
}
}
在index文件下对组件定义的相关内容,不会改变组件内部的东西,只是放大和缩小而已
三、自定义组件的成员变量
为了更好的让自定义组件灵活使用,ArkTS允许对自定义组件里面的成员变量进行赋值,
但是不允许对成员函数赋值,如果要改变函数,则需要使用箭头函数的形式来调用函数
示例:
@Preview
@Component
export default struct HelloComponent {
@State mes: string = '这是一个可以传参的组件'
showDialog = () => {
}
build() {
Column({ space: 10 }) {
Text(this.mes)
Button('点击按钮').onClick(this.showDialog) // 点击按钮出发showDialog成员变量(回调函数)
}
.width("100%")
.height(100)
.border({
width: 1
})
.padding(5)
.borderRadius(10)
.justifyContent(FlexAlign.Center)
}
}
import HelloComponent from '../components/HelloComponent'
@Entry
@Component
struct Index {
build() {
Column() {
Column({ space: 15 }) {
HelloComponent()
.width(200)
HelloComponent({ mes: '你好世界' }) // 上面两个没有定义showDialog部分,所以点击按钮不会有反应
.width(200)
HelloComponent({ // 这个组件点击按钮就有反应,出现一个dailog
mes: '自定义成员的箭头函数', showDialog() {
AlertDialog.show({
message: '这是一个自定义传承的箭头函数'
})
}
})
.width(200)
}
.width('100%')
.backgroundColor('#D4F6FF')
.height(500)
.justifyContent(FlexAlign.Center)
}
}
}
四、使用@BuilderParams来传递UI组件
在组件中提供一个区域,用于父组件随意构造,
当父组件没有进行构造的时候,子组件会使用默认值去填充那块区域,类似与Vue的插槽
步骤:
-
使用 @BuilderParam 来指定一个为箭头函数的成员参数,这个箭头函数要设置一个初识的默认值
-
使用 @Builder 添加默认值,赋值给到 @BuilderParam 的成员参数里面
-
在子组件合适的地方调用 @BuilderParam 的成员参数,这时候就相当于建立了一个插槽
-
在父组件里面调用子组件,如果不传结构,则显示默认结构,如果传入结构,则在子组件的大括号里面传入对应结果(只适用于单个 @BuilderParam )
示例:
组件内容
@Preview
@Component
export default struct MyPanel {
@State title: string = ''
@State next: string = ''
// 构造一个箭头函数,表名这是一个可以存入结构的地方,并且默认结构是defBuilder
@BuilderParam ContentBuilder: () => void = this.defBuilder
//创建默认结构,同时方便后面引用,其实本质就是创造了一个插槽
@Builder
defBuilder() {
Text('默认文本')
}
build() {
Column({ space: 10 }) {
Row() {
Text(this.title)
Text(this.next)
}
.justifyContent(FlexAlign.SpaceBetween)
.padding(10)
.width("90%")
.borderWidth({
bottom: 1
})
Column() {
this.ContentBuilder() // 调用默认结构,当父组件传承过来的时候,就会覆盖这部分的内容,本质上其实就创建了一个区域来 } // 存放父组件传过来的结构
}
.backgroundColor(Color.White)
.height(200)
.padding(20)
.borderRadius(25)
}
}
父组件调用
import MyPanel from '../components/MyPanel'
@Entry
@Component
struct Index {
build() {
Column() {
Column({ space: 15 }) {
// 直接调用,这时候子组件的Column区域就会显示默认的结构,即一个文本内容
MyPanel({ title: '我的收藏', next: '收藏内容 >' })
// 覆盖调用,大括号里面的东西就会显示父组件自定义的内容,同时会放在子组件的Column区域
MyPanel({ title: '我的订单', next: '全部订单 >' }) {
Text('自定义默认内容')
Text('自定义默认内容')
Text('自定义默认内容')
}
}
.width('100%')
.backgroundColor('#D4F6FF')
.height(500)
.justifyContent(FlexAlign.Center)
}
.width("100%")
}
}
五、使用多个@BuilderParams来传递UI组件
这种情况,就不能再自定义组件后面的大括号里面直接去定义了,这时候就得在父组件里面额外定义一个 @Builder 来赋值个组件中对应的 @BuilderParams,否则 BuilderParams 始终会是默认值
示例:
子组件:
@Component
export default struct LotSorts {
// 定义两个结构参数,用来给父组件赋值,同时在子组件中呈现
@BuilderParam aBuilder: () => void = this.aDefBuilder
@BuilderParam bBuilder: () => void = this.bDefBuilder
//定义默认组件样式
@Builder
aDefBuilder() {
Text('默认标题')
Text('下一页')
}
@Builder
bDefBuilder() {
Text('默认文本')
}
build() {
Column() {
Row() {
this.aBuilder()
}
.justifyContent(FlexAlign.SpaceBetween)
.padding(10)
.width("90%")
.borderWidth({
bottom: 1
})
Column() {
this.bBuilder()
}
}
.backgroundColor(Color.White)
.height(200)
.padding(20)
.borderRadius(25)
}
}
父组件:
import LotSorts from '../components/LotSorts'
@Entry
@Component
struct Index {
//在父组件中单独定义几个结构,用于赋值到子组件
@Builder
aDefBuilder() {
Text('我的收藏')
Text('详细页面 >')
}
@Builder
bDefBuilder() {
Text('自定义默认内容')
Text('自定义默认内容')
Text('自定义默认内容')
}
build() {
Column() {
Column({ space: 15 }) {
LotSorts()
LotSorts({
aBuilder: this.aDefBuilder, //注意这里的赋值方法
bBuilder: this.bDefBuilder
})
}
.width('100%')
.backgroundColor('#D4F6FF')
.height(500)
.justifyContent(FlexAlign.Center)
}
.width("100%")
}
}