-
@prop 单向同步
允许装饰的变量类型 @prpo只支持string,number、boolean、enum类型
父组件是对象类型,子组件是对象属性
不可以是数组、any
不允许子组件初始化
-
@Link 双向同步
父子类型一致:string,number,boolean、enum、object、class,以及他们的数组
数组中元素增删改都会引起刷新
嵌套类型以及数组中的对象属性无法触发视图更新
不允许子组件初始化
@Provide 和Cousume可以夸组件提供类似于@state和@link装饰器的双向同步(类似于vue中的发布和订阅)
// @ts-nocheck
/**
* 任务条数量统计
*/
class Task {
static id:number = 1
name:string = `任务${Task.id++}`
finished: boolean = false
}
class StartInfo{
totalTask:number = 0
finishTask:number = 0
}
// 统一的卡片样式
@Styles function card(){
.width('90%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({redius: 6, color:'#1F000000', offsetX:2, offsetY:4 })
}
// 任务完成样式
@Extend(Text) function finishTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
@Component
struct TaskProgress {
@Prop finishTask:number
@Prop totalTask:number
build() {
Row() {
Text('任务进度:')
.fontWeight(FontWeight.Bold)
.fontSize(30)
Stack() {
Progress({
value: this.finishTask,
total: this.totalTask,
type: ProgressType.ScaleRing
})
.width(100)
Row() {
Text(this.finishTask.toString())
.fontSize(30)
.fontWeight(FontWeight.Bold)
Text(' / ' + this.totalTask.toString())
.fontSize(24)
.fontWeight(FontWeight.Bold)
}
}
}
.justifyContent(FlexAlign.SpaceEvenly)
.card()
.margin({ top: 20, bottom: 10 })
}
}
@Component
struct TaskList{
// @Link finishTask:number
// @Link totalTask:number
@Link stat:StartInfo
// 任务数组
@State taskList: Task[] = []
build() {
Column(){
Button('新增任务')
.width(200)
.onClick(() => {
this.taskList.push(new Task())
this.handleTaskChange()
})
.margin({bottom:20})
List({space:10}){
ForEach(
this.taskList,
(task:Task,index)=>{
ListItem(){
Row(){
Text(task.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Checkbox()
.select(task.finished)
.onChange((val)=>{
task.finished = val
this.handleTaskChange()
})
}
.card()
.margin({left:20})
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.DeleteButton(index)})
}
)
}
.layoutWeight(1)
}
}
@Builder DeleteButton(index:number){
Button(){
Image($r("app.media.app_icon"))
.width(20)
.height(20)
}
.type(ButtonType.Circle)
.width(40)
.height(40)
.margin(20)
.onClick(()=>{
this.taskList.splice(index,1)
this.handleTaskChange()
})
}
handleTaskChange(){
// 更新任务数量
this.stat.totalTask = this.taskList.length
// 更新已完成任务数量
this.stat.finishTask = this.taskList.filter((item)=>item.finished).length
}
}
@Entry
@Component
struct PropPage {
// // 总任务数量
// @State totalTask: number = 0
//
// //已完成任务数量
// @State finishTask: number = 0
@State stat: StatInfo = new StartInfo()
build() {
Column({ space: 10 }) {
TaskProgress({totalTask:this.stat.totalTask,finishTask:this.stat.finishTask})
// Link是引用类型,必须用特殊符号隔开
TaskList({stat:$stat})
}
.width('100%')
.height('100%')
.backgroundColor("#F1F2F3")
}
}