鸿蒙开发-注解
8.0 注解-@Entry
8.1 注解-@Extend 特定组件继承
// @Extend(组件名)
// function 函数名 (参数, 参数2) {
//
// }
@Extend(Text)
function textFn () {
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
@Extend(Text)
function bannerItem (bgColor: ResourceColor, msg: string) {
.textAlign(TextAlign.Center)
.backgroundColor(bgColor)
.fontColor(Color.White)
.fontSize(30)
.onClick(() => {
AlertDialog.show({
message: msg
})
})
}
----------------------------调用------------------------------
Text(this.message)
.textFn()
Swiper() {
Text('1')
.bannerItem(Color.Orange, '轮播图1号')
Text('2')
.bannerItem(Color.Brown, '轮播图2号')
Text('3')
.bannerItem(Color.Green, '轮播图3号')
}
.width('100%')
.height(160)
8.2注解-@Styles 通用组件设置值
// 1. 全局定义
@Styles function commonStyles () {
.width(100)
.height(100)
}
@Entry
@Component
struct StylesDemo {
@State message: string = '@styles';
@State bgColor: ResourceColor = Color.Gray
// 2. 组件内定义(才能通过this访问到自己的状态)
@Styles setBg() {
.backgroundColor(this.bgColor)
.onClick(() => {
this.bgColor = Color.Green
})
}
build() {
Column({ space: 10 }) {
Text(this.message)
.fontColor(Color.White)
.commonStyles()
.setBg()
Column() {}
.commonStyles()
.setBg()
Button('按钮')
.commonStyles()
.setBg()
}
.width('100%')
.height('100%')
}
}
8.3注解-@Builder 构建一个全局组件
// 全局 Builder
@Builder
function navItem(icon: ResourceStr, txt: string) {
Column({ space: 10 }) {
Image(icon)
.width('80%')
Text(txt)
}
.width('25%')
.onClick(() => {
AlertDialog.show({
message: '点了' + txt
})
})
}
@Entry
@Component
struct BuilderDemo {
@State message: string = '@Builder';
@Builder
navItem(icon: ResourceStr, txt: string) {
Column({ space: 10 }) {
Image(icon)
.width('80%')
Text(txt)
}
.width('25%')
.onClick(() => {
AlertDialog.show({
message: '点了' + txt + this.message
})
})
}
build() {
Column({ space: 20 }) {
Text(this.message)
.fontSize(30)
Row() {
Row() {
navItem($r('app.media.ic_reuse_01'), '阿里拍卖')
navItem($r('app.media.ic_reuse_02'), '菜鸟')
this.navItem($r('app.media.ic_reuse_03'), '巴巴农场')
this.navItem($r('app.media.ic_reuse_04'), '阿里药房')
}
}
}
.width('100%')
.height('100%')
}
}
8.4 注解-@Component 自定义组件
自定义组件生命周期
@Component
struct MyCom {
@State count: number = 1
build() {
Row() {
Text(this.count.toString())
.fontColor(Color.White)
.margin(10)
Button('按钮')
.onClick(() => {
this.count++
})
}
}
}
@Component
struct MyHeader {
build() {
Row() {
Text('我是头部')
.fontColor(Color.White)
}
.width('100%')
.height(50)
.backgroundColor(Color.Brown)
}
}
@Component
struct MyMain {
build() {
Column() {
// 将相同的业务逻辑, 封装成一个通用的组件
MyCom()
MyCom()
MyCom()
}
.layoutWeight(1)
.width('100%')
.backgroundColor(Color.Gray)
}
}
@Component
struct MyFooter {
build() {
Row() {
Text('我是底部')
}
.width('100%')
.height(50)
.backgroundColor(Color.Green)
}
}
@Entry
@Component
struct Index {
build() {
Column() {
MyHeader()
MyMain()
MyFooter()
}
}
}
---------------------------------------1.导出组件------------------
//加入这个@Preview可以预览页面
@Preview
@Component
export struct HelloCom {
build() {
Row() {
Text('自定义组件')
Button('按钮')
}
.width(200)
.height(50)
.backgroundColor(Color.Orange)
}
}
-----------------------------------2.导入组件----------------------------
import { HelloCom } from '../components/HelloCom'
@Entry
@Component
struct Index {
build() {
Column() {
HelloCom()
.width(250)
.height(60)
.backgroundColor(Color.Gray)
.onClick(() => {
AlertDialog.show({
message: '测试点击'
})
})
}
}
}
--------------------------成员变量函数重新赋值----------------------
通俗的讲就是带等号的重新赋值
@Component
struct MyPanel {
// 成员变量 - 数据
title: string = '默认的大标题'
extra: string = '查看更多 >'
// 成员变量 - 函数 - 可以外部传入覆盖的
getMore = () => {
AlertDialog.show({
message: '查看更多'
})
}
// 成员函数 - 不可以外部传入覆盖
sayHi() {
AlertDialog.show({
message: '打招呼, 你好'
})
}
build() {
Column() {
Row() {
Text(this.title).fontSize(18)
Text(this.extra).fontSize(18)
.onClick(() => {
this.getMore()
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
Row() {
Text('内容部分').fontSize(18)
Button('按钮')
.onClick(() => {
this.sayHi()
})
}
.padding(20)
}
.padding(10)
.width('100%')
.height(200)
.margin({ bottom: 20 })
.borderRadius(10)
.backgroundColor(Color.White)
}
}
@Entry
@Component
struct Index {
build() {
Column() {
MyPanel({
title: '我的订单',
extra: '全部订单 > ',
getMore() {
AlertDialog.show({
message: '点击了全部订单'
})
}
})
MyPanel({
title: '小米有品重酬',
extra: '7款重酬中 >',
getMore() {
AlertDialog.show({
message: '查看7款重酬'
})
}
})
}
.width('100%')
.height('100%')
.backgroundColor('#ccc')
.padding(20)
}
}
8.5 注解-@BuilderParam 可以让自定义组件外部传递UI,相当于vue的插槽
@Component
struct MyPanel {
// 成员变量 - 数据
title: string = '默认的大标题'
extra: string = '查看更多 >'
// 成员变量 - 函数 - 可以外部传入覆盖的
getMore = () => {
AlertDialog.show({
message: '查看更多'
})
}
// 成员函数 - 不可以外部传入覆盖
sayHi() {
AlertDialog.show({
message: '打招呼, 你好'
})
}
@BuilderParam ContentBuilder: () => void = this.defaultBuilder
@Builder defaultBuilder () {
Text('默认文本')
}
build() {
Column() {
Row() {
Text(this.title).fontSize(18)
Text(this.extra).fontSize(18)
.onClick(() => {
this.getMore()
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
Row() {
// 这里的结构不能写死, 需要通过 BuilderParam 来进行构建
this.ContentBuilder()
}
.padding(20)
}
.padding(10)
.width('100%')
.height(200)
.margin({ bottom: 20 })
.borderRadius(10)
.backgroundColor(Color.White)
}
}
@Entry
@Component
struct Index {
build() {
Column() {
MyPanel({
title: '我的订单',
extra: '全部订单 > ',
getMore() {
AlertDialog.show({
message: '点击了全部订单'
})
}
}) {
Column() {
Text('我是订单 - 相关的文本')
Text('我是订单 - 相关的文本')
Text('我是订单 - 相关的文本')
}
}
MyPanel({
title: '小米有品重酬',
extra: '7款重酬中 >',
getMore() {
AlertDialog.show({
message: '查看7款重酬'
})
}
}) {
Column() {
Button('我是小米重酬的按钮')
Button('我是小米重酬的按钮')
Button('我是小米重酬的按钮')
}
}
}
.width('100%')
.height('100%')
.backgroundColor('#ccc')
.padding(20)
}
}
----------------------------多BuilderParam-----------------
@Component
struct MyCard {
@BuilderParam tBuilder: () => void = this.tDefaultBuilder
@BuilderParam cBuilder: () => void = this.cDefaultBuilder
@Builder tDefaultBuilder () {
Text('我是默认的大标题')
}
@Builder cDefaultBuilder () {
Text('我是默认的内容')
}
build() {
// 卡片组件
Column() {
// 标题部分
Row() {
this.tBuilder()
}
.height(30)
.width('100%')
.border({ color: '#ccc', width: { bottom: 1 }})
.padding({ left: 10 })
// 内容部分
Row() {
this.cBuilder()
}
.width('100%')
.padding(10)
}
.width('100%')
.height(100)
.backgroundColor(Color.White)
.borderRadius(10)
.justifyContent(FlexAlign.Start)
}
}
@Entry
@Component
struct Index {
@Builder ftBuilder () {
Text('我是传入的大标题结构')
}
@Builder fcBuilder () {
Text('我是内容部分')
Text('我是内容部分')
Text('我是内容部分')
}
build() {
Column({ space: 10 }) {
MyCard()
MyCard({
tBuilder: this.ftBuilder,
cBuilder: this.fcBuilder
})
}
.width('100%')
.height('100%')
.padding(20)
.backgroundColor('#ccc')
}
}
8.6注解-@State 状态变量
// 注意点:
// 1. 普通变量, 只能在初始化时渲染, 后续变化了, 也不会引起更新
// 2. 状态变量, 被装饰器修饰, 值的改变, 会 [自动] 引起 界面的刷新
// 组件外的[普通变量] 不需要this即可访问
let myName: string = '吕布'
@Entry
@Component
struct Index {
// 组件内的[普通变量] this.xxx
myAge: number = 18
// 组件内的[状态变量] this.xxx
@State myMsg: string = 'hello 黑马'
build() {
Column() {
Text(myName).onClick(() => {
myName = '貂蝉'
console.log('myName', myName)
})
Text(this.myAge.toString()).onClick(() => {
this.myAge = 200
console.log('myAge', this.myAge)
})
Text(this.myMsg).onClick(() => {
this.myMsg = '你好 状态'
})
}
}
}
-----------------------复杂类型更改方式-----------------------
//这么更改
//this.person.car = {
// name: '老爷车'
// }
interface Car {
name: string
}
interface Person {
name: string
car: Car
}
const obj: Person = {
name: 'zs',
car: {
name: '小黄车'
}
}
console.log('查看第一层属性', Object.keys(obj))
@Entry
@Component
struct Index {
// 状态变量
// 1. string number boolean 可以直接监视到变化
@State message: string = 'hello world'
// 2. 复杂类型 object class, 第一层随便改, 嵌套需要进行整个嵌套对象的替换
@State person: Person = {
name: 'jack',
car: {
name: '宝马车'
}
}
build() {
Column() {
Text(this.message).fontSize(20)
Button('改message').onClick(() => {
this.message = '你好'
})
Text(JSON.stringify(this.person))
Button('改person').onClick(() => {
// this.person = {
// name: 'amy',
// car: {
// name: '保时捷'
// }
// }
this.person.name = 'tony'
// 如果不是对象的第一层属性, 修改时, 需要修改整个嵌套的对象
this.person.car.name = '小火车'
// console.log('car name', this.person.car.name)
this.person.car = {
name: '老爷车'
}
})
}
}
}
8.7 注解-@Prop父传子,让值变化
//@Prop加了这个后,父组件更改这个值,子组件也会跟着变化
@Component
struct SonCom {
// 保证父组件的数据变化了, 能够往下响应式的更新
@Prop sCar: string = ''
changeCar = (newCar: string) => {}
build() {
Column() {
Text(`子组件 ${this.sCar}`)
Button('换车').onClick((event: ClickEvent) => {
// 1. prop传值 → 单向传递
// 子组件, 可以修改到 prop 传值, 但是修改的更新不会同步到父组件
// 通常不太会直接修改 prop 传值, 父组件的状态一旦变化, 会自动向下同步
// 修改就被覆盖了
// this.sCar = '小黄车'
// 2. 如果实在想更新, 希望保证父子同步 => 调用父组件传递过来的方法
// 如果没有写箭头函数, 意味着, this 指向 调用者, 而此处执行环境 this → 子组件
this.changeCar('蹦蹦车')
})
}
.padding(20)
.backgroundColor(Color.Orange)
}
}
@Entry
@Component
struct FatherCom {
@State fCar:string = '劳斯莱斯'
build() {
Column() {
Text(`父组件 - ${this.fCar}`)
Button('换车').onClick(() => {
this.fCar = '三轮车'
})
SonCom({
sCar: this.fCar,
// 这里必须要用箭头函数, 否则会有 this 指向的问题
// 使用箭头函数的好处, 可以使用外部环境的 this, 不受传递过去后的执行环境影响
// 希望此处 this 指向 父组件
changeCar: (newCar: string) => {
this.fCar = newCar
}
})
}
.padding(50)
.backgroundColor(Color.Pink)
}
}
8.8注解-@Link 父传子 子传父,数据双向同步
interface Person {
name: string
age: number
}
@Entry
@Component
// 父组件
struct KnowledgePage {
@State count: number = 0
@State person: Person = {
name: 'zs',
age: 18
}
build() {
Column() {
Text('父组件')
.fontSize(30)
Text(this.count.toString())
Text(JSON.stringify(this.person))
Button('修改数据')
.onClick(() => {
this.count++
})
SonComponent({
count: this.count,
person: this.person
})
}
.padding(10)
.height('100%')
.backgroundColor('#eee')
.width('100%')
.alignItems(HorizontalAlign.Center)
.padding({ top: 100 })
}
}
@Component
// 子组件
struct SonComponent {
@Link count: number
@Link person: Person
// 编写 UI
build() {
Column({ space: 20 }) {
Text('我是子组件')
.fontSize(20)
Text(this.count.toString())
Text(JSON.stringify(this.person))
Column() {
Button('修改数据')
.onClick(() => {
// this.count++
this.person.age++
})
}
}
.backgroundColor('#a6c398')
.alignItems(HorizontalAlign.Center)
.width('80%')
.margin({ top: 100 })
.padding(10)
.borderRadius(10)
}
}
8.9注解- @Consume和@Provide父与子孙后代简单数据同步
interface Car {
name: string
brand: string
}
@Entry
@Component
// 顶级组件
struct RootComponent {
@Provide themeColor: string = 'yellow'
@Provide car: Car = {
name: '小黄',
brand: '美团'
}
build() {
Column() {
Text('顶级组件')
.fontSize(30)
.fontWeight(900)
Text(this.themeColor)
Text(JSON.stringify(this.car))
// 二级组件
ParentComponent()
ParentComponent()
}
.padding(10)
.height('100%')
.backgroundColor('#ccc')
.width('100%')
.alignItems(HorizontalAlign.Center)
.padding({ top: 100 })
}
}
@Component
// 二级组件
struct ParentComponent {
@Consume themeColor: string
// 编写 UI
build() {
Column({ space: 20 }) {
Text('我是二级组件')
.fontSize(22)
.fontWeight(900)
Text(this.themeColor)
// 内层子组件
SonComponent()
}
.backgroundColor('#a6c398')
.alignItems(HorizontalAlign.Center)
.width('90%')
.margin({ top: 50 })
.padding(10)
.borderRadius(10)
}
}
@Component
// 内层组件
struct SonComponent {
@Consume themeColor: string
@Consume car: Car
// 编写 UI
build() {
Column({ space: 20 }) {
Text('我是内层组件' + this.themeColor)
.fontSize(20)
.fontWeight(900)
.onClick(() => {
// this.themeColor = 'orange'
this.car.name = '小绿'
})
Text(JSON.stringify(this.car))
}
.backgroundColor('#bf94e4')
.alignItems(HorizontalAlign.Center)
.width('90%')
.margin({ top: 50 })
.padding(10)
.borderRadius(10)
}
}
8.10注解- @Observed和@ObjectLink父与子孙后代复杂数据同步(多层数据)
interface IPerson {
id: number
name: string
age: number
}
@Observed
class Person {
id: number
name: string
age: number
constructor(obj: IPerson) {
this.id = obj.id
this.name = obj.name
this.age = obj.age
}
}
@Entry
@Component
struct ObservedAndLink {
@State personList: Person[] = [
new Person({
id: 1,
name: '张三',
age: 18
}),
new Person({
id: 2,
name: '李四',
age: 19
}),
new Person({
id: 3,
name: '王五',
age: 20
})
]
build() {
Column({ space: 20 }) {
Text('父组件')
.fontSize(30)
List({ space: 10 }) {
ForEach(this.personList, (item: Person, index: number) => {
ItemCom({
info: item,
addAge: () => {
// 修改嵌套的数据 => 普通的情况, 监视不到更新
item.age++ // 如果能监视到
AlertDialog.show({
message: JSON.stringify(this.personList)
})
// this.personList.splice(index, 1, item) // 无需手动替换更新
}
})
})
}
}
.backgroundColor('#cbe69b')
.width('100%')
.height('100%')
.padding(20)
}
}
@Component
struct ItemCom {
@ObjectLink info: Person
addAge = () => {
}
build() {
ListItem() {
Row({ space: 10 }) {
Text('姓名:' + this.info.name)
Text('年龄:' + this.info.age)
Blank()
Button('修改数据')
.onClick(() => {
// this.addAge()
this.info.age++
})
}
.backgroundColor(Color.Pink)
.padding(10)
.width('100%')
}
}
}