1.@state
import { Header } from '../common/components/CommonComponents';
class Person{
name: string
age: number
gf: Person
constructor(name: string, age: number, gf?: Person) {
this.name = name
this.age = age
this.gf = gf
}
}
@Entry
@Component
struct StatePage2 {
idx: number = 1
@State p: Person = new Person('Jack', 21, new Person('柔丝', 18))
@State gfs: Person[] = [
new Person('柔丝', 18),
new Person('露西', 19),
]
build() {
Column({space: 10}) {
Header()
Text(`${this.p.name} : ${this.p.age}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.p.age++
})
Text(`${this.p.gf.name} : ${this.p.gf.age}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.p.gf.age++
})
Button('添加')
.onClick(() => {
this.gfs.push(new Person('女友' + this.idx++, 20))
})
Text('=女友列表=')
.fontSize(50)
.fontWeight(FontWeight.Bold)
ForEach(
this.gfs,
(p, index) => {
Row(){
Text(`${p.name} : ${p.age}`)
.fontSize(30)
.onClick(() => {
this.gfs[index] = new Person(p.name, p.age+1)
})
Button('删除')
.onClick(() => {
this.gfs.splice(index, 1)
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
)
}
.width('100%')
.height('100%')
.padding(10)
}
}
@Component
struct StatePage {
@State name: string = 'Jack'
@State age: number = 21
build() {
Column() {
Text(`${this.name} : ${this.age}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.age++
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
2. @Prop和@Link装饰器
当父子组件之间需要数据同步时,可以使用@Prop和@Link装饰器
3. @Provide和@Consume可以跨组件使用
@Provide和@Consume和@state和@Link的双向同步,在使用过程中父组件不需要给子组件内部传入参数,这两个修饰符会内部自己进行数据消费操作,但是比较消耗性能,尽量减少使用
4. @Observed和@ObjectLink
@Observed和@ObjectLink装饰器用于在涉及嵌套对象或者数组元素为对象的场景中进行双向数据同步
5.任务案例
5.1@state
import { Header } from '../common/components/CommonComponents';
// 任务类
@Observed
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态:是否完成
finished: boolean = false
}
// 统一的卡片样式
@Styles function card(){
.width('95%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
@Entry
@Component
struct satePage1 {
//总任务数量
@State totalTask: number = 0
//已完成任务数量
@State finishTask: number = 0
//任务数组
@State tasks: Task[] = []
handleTaskChange(){
//1.更新任务总数量
this.totalTask = this.tasks.length
//2.更新已完成任务数量
this.finishTask=this.tasks.filter(item=>item.finished).length
}
build() {
Column({ space: 10 }) {
Header()
//1.任务进度卡片
Row() {
Text('任务进度:')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value:this.finishTask,
total:this.totalTask,
type:ProgressType.Ring
})
Row() {
Text(this.finishTask.toString())
.fontSize(24)
.fontColor("#36D")
Text('/' + this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({ top: 20, bottom: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
//2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(()=>{
//1.新增任务数据
this.tasks.push(new Task())
//2.更新已完成任务数量
this.handleTaskChange()
})
//3.任务列表
List({space:10}){
ForEach(this.tasks,(item:Task,index)=>{
ListItem(){
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val=>{
//1.更新当前任务
item.finished=val
//2.更新已完成任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.DeleteButton(index)})
})
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index:number){
Button(){
Image($r('app.media.ic_public_delete_filled'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(()=>{
this.tasks.splice(index,1)
this.handleTaskChange()
})
}
}
5.2@prop单向同步 子组件只读取父组件
// 任务类
@Observed
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态:是否完成
finished: boolean = false
}
// 统一的卡片样式
@Styles function card(){
.width('95%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
@Entry
@Component
struct satePage1 {
//总任务数量
@State totalTask: number = 0
//已完成任务数量
@State finishTask: number = 0
//任务数组
@State tasks: Task[] = []
handleTaskChange(){
//1.更新任务总数量
this.totalTask = this.tasks.length
//2.更新已完成任务数量
this.finishTask=this.tasks.filter(item=>item.finished).length
}
build() {
Column({ space: 10 }) {
TaskStatistics({totalTask:this.totalTask,finishTask:this.finishTask})
//2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(()=>{
//1.新增任务数据
this.tasks.push(new Task())
//2.更新已完成任务数量
this.handleTaskChange()
})
//3.任务列表
List({space:10}){
ForEach(this.tasks,(item:Task,index)=>{
ListItem(){
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val=>{
//1.更新当前任务
item.finished=val
//2.更新已完成任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.DeleteButton(index)})
})
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index:number){
Button(){
Image($r('app.media.ic_public_delete_filled'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(()=>{
this.tasks.splice(index,1)
this.handleTaskChange()
})
}
}
@Component
struct TaskStatistics{
@Prop finishTask: number
@Prop totalTask: number
build() {
//1.任务进度卡片
Row() {
Text('任务进度:')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value:this.finishTask,
total:this.totalTask,
type:ProgressType.Ring
})
Row() {
Text(this.finishTask.toString())
.fontSize(24)
.fontColor("#36D")
Text('/' + this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({ top: 20, bottom: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
}
}
5.3@Link 双向同步 子组件读区和修改父组件
// 任务类
@Observed
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态:是否完成
finished: boolean = false
}
// 统一的卡片样式
@Styles function card(){
.width('95%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
@Entry
@Component
struct satePage1 {
//总任务数量
@State totalTask: number = 0
//已完成任务数量
@State finishTask: number = 0
//任务数组
@State tasks: Task[] = []
build() {
Column({ space: 10 }) {
TaskStatistics({totalTask:this.totalTask,finishTask:this.finishTask})
TaskList({totalTask:$totalTask,finishTask:$finishTask})
}
}
}
@Component
struct TaskStatistics{
@Prop finishTask: number
@Prop totalTask: number
build() {
//1.任务进度卡片
Row() {
Text('任务进度:')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value:this.finishTask,
total:this.totalTask,
type:ProgressType.Ring
})
Row() {
Text(this.finishTask.toString())
.fontSize(24)
.fontColor("#36D")
Text('/' + this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({ top: 20, bottom: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
}
}
@Component
struct TaskList {
@State tasks:Task[]=[]
//总任务数量
@Link totalTask: number
//已完成任务数量
@Link finishTask: number
handleTaskChange(){
//1.更新任务总数量
this.totalTask = this.tasks.length
//2.更新已完成任务数量
this.finishTask=this.tasks.filter(item=>item.finished).length
}
build() {
Column(){
//2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(()=>{
//1.新增任务数据
this.tasks.push(new Task())
//2.更新已完成任务数量
this.handleTaskChange()
})
//3.任务列表
List({space:10}){
ForEach(this.tasks,(item:Task,index)=>{
ListItem(){
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val=>{
//1.更新当前任务
item.finished=val
//2.更新已完成任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.DeleteButton(index)})
})
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index:number){
Button(){
Image($r('app.media.ic_public_delete_filled'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(()=>{
this.tasks.splice(index,1)
this.handleTaskChange()
})
}
}
5.4 @Provide和@Consume
import { Header } from '../common/components/CommonComponents';
// 任务类
@Observed
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态:是否完成
finished: boolean = false
}
// 统一的卡片样式
@Styles function card(){
.width('95%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
// 任务统计信息
class StatInfo {
totalTask: number = 0
finishTask: number = 0
}
@Entry
@Component
struct PropPage {
// 统计信息
@Provide stat: StatInfo = new StatInfo()
build() {
Column({space: 10}){
Header()
// 1.任务进度卡片
TaskStatistics()
// 2.任务列表
TaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskStatistics {
@Consume stat: StatInfo
build() {
Row(){
Text('任务进度:')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value: this.stat.finishTask,
total: this.stat.totalTask,
type: ProgressType.Ring
})
.width(100)
Row(){
Text(this.stat.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / ' + this.stat.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 5, bottom: 10})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
@Component
struct TaskList {
// 总任务数量
@Consume stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 1.更新任务总数量
this.stat.totalTask = this.tasks.length
// 2.更新已完成任务数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column(){
// 2.新增任务按钮
Button('新增任务')
.width(200)
.margin({bottom: 10})
.onClick(() => {
// 1.新增任务数据
this.tasks.push(new Task())
// 2.更新任务总数量
this.handleTaskChange()
})
// 3.任务列表
List({space: 10}){
ForEach(
this.tasks,
(item: Task, index) => {
ListItem(){
TaskItem({item: item, onTaskChange: this.handleTaskChange.bind(this)})
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number){
Button(){
Image($r('app.media.ic_public_delete_filled'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(() => {
this.tasks.splice(index, 1)
this.handleTaskChange()
})
}
}
@Component
struct TaskItem {
@ObjectLink item: Task
onTaskChange: () => void
build() {
Row(){
if(this.item.finished){
Text(this.item.name)
.finishedTask()
}else{
Text(this.item.name)
}
Checkbox()
.select(this.item.finished)
.onChange(val => {
// 1.更新当前任务状态
this.item.finished = val
// 2.更新已完成任务数量
this.onTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
}