状态管理
- @State
- @Prop和@Link
- @Provide和@Consume
- @observed和@0bjectLink
@State
上图,此时点击文字,会发生变化
如果你修改的里面没有在预览器看到变化,可以刷新预览器
如果是模拟器想展示非index页面,需要用到页面导航
普通数据类型状态
@Entry
@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)
}
}
对象数据类型的状态
和普通数据类型的状态一样,状态的变化可以触发视图的渲染
class Person{
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
@Entry
@Component
struct StatePage2 {
@State p:Person = new Person('jeck', 21)
build() {
Column(){
Text(`${this.p.name} : ${this.p.age}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.p.age++
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
嵌套对象的状态
注意:嵌套对象的状态发生变化,无法触发视图的更新渲染
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 {
@State p:Person = new Person('jeck', 21, new Person('Rous', 18))
build() {
Column(){
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++
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
数组类型的状态
注意: 数组里的元素发生变化,会触发视图更新,如下:
[‘jeck’,‘rous’,‘tom’,new Person(‘zs’,18)] 只是一个数组,当我们删除,或者添加一个元素的时候
视图会更新。
但是当我们修改数组里的对象里的属性的时候,不会触发更新 如[1,'a',{name:zs, age:18}]
我们修改name属性不会触发更新
比如:[‘jeck’,‘rous’,‘tom’,new Person(‘zs’,22)],我们修改了数组里面的对象> 里面的属性,不会触发更新
因为我们修改了数组里面的对象里面的属性,不会触发更新
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('jeck', 21, new Person('Rous', 18))
@State gfs: Person[] = [
new Person('柔丝', 18),
new Person('露西', 19)
]
build() {
Column(){
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%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
案例
结构和样式初始化
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 PropPage {
// 总任务数量
@State totalTask: number = 0
// 已完成任务数量
@State finnishTask: number = 0
// 任务数组
@State tasks: Task[] = []
build(){
Column({space: 10}){
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
大致完成效果
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 PropPage {
// 总任务数量
@State totalTask: number = 0
// 已完成任务数量
@State finishTask: number = 0
// 任务数组
@State tasks: Task[] = []
build(){
Column({space: 10}){
// 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(() => {
// 2.2 新增任务数据
this.tasks.push(new Task())
// 2.3 新增任务总量
this.totalTask = this.tasks.length
})
// 3.任务列表
ForEach(
this.tasks,
(item: Task,index) => {
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val => {
// 3.1更新当前的状态
item.finished = val
// 3.2 更新已完成的状态
this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
})
}
}
)
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
接下来优化
封装一个函数
handleTaskChange(){
// 新增任务总量
this.totalTask = this.tasks.length
// 更新已完成的状态数量
this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
使用函数
使用
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 PropPage {
// 总任务数量
@State totalTask: number = 0
// 已完成任务数量
@State finishTask: number = 0
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 新增任务总量
this.totalTask = this.tasks.length
// 更新已完成的状态数量
this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
build(){
Column({space: 10}){
// 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(() => {
// 2.2 新增任务数据
this.tasks.push(new Task())
// 2.3 新增任务总量
// this.totalTask = this.tasks.length
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 => {
// 3.1更新当前的状态
item.finished = val
// 3.2 更新已完成的状态数量
// this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.alignListItem(ListItemAlign.Center) // 集合中元素的对齐方式
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
@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() // 跟新数量
})
}
}
基于上个小案例,学习@Prop和@Link,@Provide和@Consume
@Prop和@L ink
上个小案例,平铺直叙的写发,结构不清晰,可读性差,我们可以将其封装成子组件
在入口组件,引用其他组件,这样结构清晰
开始封装改造
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 PropPage {
// 总任务数量
@State totalTask: number = 0
// 已完成任务数量
@State finishTask: number = 0
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 新增任务总量
this.totalTask = this.tasks.length
// 更新已完成的状态数量
this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
build(){
Column({space: 10}){
// 1.任务进度
TaskStatistics({finishTask: this.finishTask, totalTask: this.totalTask})
// 2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 2.2 新增任务数据
this.tasks.push(new Task())
// 2.3 新增任务总量
// this.totalTask = this.tasks.length
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 => {
// 3.1更新当前的状态
item.finished = val
// 3.2 更新已完成的状态数量
// this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.alignListItem(ListItemAlign.Center) // 集合中元素的对齐方式
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
@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 修饰的变量不可以初始化,等待父组件传给他值
@Prop totalTask: number
build() {
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)
}
}
双向传值
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 PropPage {
// 总任务数量
@State totalTask: number = 0
// 已完成任务数量
@State finishTask: number = 0
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 新增任务总量
this.totalTask = this.tasks.length
// 更新已完成的状态数量
this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
build(){
Column({space: 10}){
// 1.任务进度
TaskStatistics({finishTask: this.finishTask, totalTask: this.totalTask})
// 2.新增任务按钮
TaskList({finishTask: $finishTask, totalTask: $totalTask})
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskStatistics{
@Prop finishTask: number // Prop 修饰的变量不可以初始化,等待父组件传给他值
@Prop totalTask: number
build() {
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 {
// 总任务数量
@Link totalTask: number
// 已完成任务数量
@Link finishTask: number
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 新增任务总量
this.totalTask = this.tasks.length
// 更新已完成的状态数量
this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
build(){
Column(){ // 注意在儿子组件里,只能有一个根元素
// 2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 2.2 新增任务数据
this.tasks.push(new Task())
// 2.3 新增任务总量
// this.totalTask = this.tasks.length
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 => {
// 3.1更新当前的状态
item.finished = val
// 3.2 更新已完成的状态数量
// this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
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()
})
}
}
我们把状态写成对象类型
。。。
。。。
class StatInfo{
// 总任务数量
totalTask: number =
// 已完成任务数量
finishTask: number = 0
}
@Entry
@Component
struct PropPage {
@State stat: StatInfo = new StatInfo()
// 任务数组
@State tasks: Task[] = []
build(){
Column({space: 10}){
// 1.任务进度
// 传的是对象的属性
TaskStatistics({finishTask: this.stat.finishTask, totalTask: this.stat.totalTask})
// 2.新增任务按钮
TaskList({stat: $stat})
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskStatistics{
@Prop finishTask: number // Prop 修饰的变量不可以初始化,等待父组件传给他值
@Prop totalTask: number
build() {
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 {
@Link stat: StatInfo
// 任务数组
@State tasks: Task[] = []
。。。
。。。
}
@Provide和@Consume
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 {
// // 总任务数量
// @State totalTask: number = 0
// // 已完成任务数量
// @State finishTask: number = 0
@Provide stat: StatInfo = new StatInfo()
build(){
Column({space: 10}){
// 1.任务进度
TaskStatistics()
// 2.新增任务按钮
TaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskStatistics{
// @Prop finishTask: number // Prop 修饰的变量不可以初始化,等待父组件传给他值
// @Prop totalTask: number
@Consume stat: StatInfo
build() {
Row(){
Text('任务进度')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value: this.stat.finishTask,
total: this.stat.totalTask,
type: ProgressType.Ring
})
Row(){
Text(this.stat.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / '+ this.stat.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 20, bottom: 10})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
@Component
struct TaskList {
// // 总任务数量
// @Link totalTask: number
// // 已完成任务数量
// @Link finishTask: number
@Consume stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 新增任务总量
this.stat.totalTask = this.tasks.length
// 更新已完成的状态数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
build(){
Column(){ // 注意在儿子组件里,只能有一个根元素
// 2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 2.2 新增任务数据
this.tasks.push(new Task())
// 2.3 新增任务总量
// this.totalTask = this.tasks.length
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 => {
// 3.1更新当前的状态
item.finished = val
// 3.2 更新已完成的状态数量
// this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
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()
})
}
}
@observed和@0bjectLink
我们之前遇到的问题
现在解决
@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 {
// // 总任务数量
// @State totalTask: number = 0
// // 已完成任务数量
// @State finishTask: number = 0
@Provide stat: StatInfo = new StatInfo()
build(){
Column({space: 10}){
// 1.任务进度
TaskStatistics()
// 2.新增任务按钮
TaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskStatistics{
// @Prop finishTask: number // Prop 修饰的变量不可以初始化,等待父组件传给他值
// @Prop totalTask: number
@Consume stat: StatInfo
build() {
Row(){
Text('任务进度')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value: this.stat.finishTask,
total: this.stat.totalTask,
type: ProgressType.Ring
})
Row(){
Text(this.stat.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / '+ this.stat.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 20, bottom: 10})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
@Component
struct TaskList {
// // 总任务数量
// @Link totalTask: number
// // 已完成任务数量
// @Link finishTask: number
@Consume stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 新增任务总量
this.stat.totalTask = this.tasks.length
// 更新已完成的状态数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
}
build(){
Column(){ // 注意在儿子组件里,只能有一个根元素
// 2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 2.2 新增任务数据
this.tasks.push(new Task())
// 2.3 新增任务总量
// this.totalTask = this.tasks.length
this.handleTaskChange()
})
// 3.任务列表
List({space: 10}){
ForEach(
this.tasks,
(item: Task,index) => {
ListItem(){
TaskItem({item: item, onTaskChange: this.handleTaskChange.bind(this)}) // 注意:handleTaskChange这个函数里使用了this,当子组件使用这个函数的时候,这个this就是子组件自己,但是子组件里没有对应的属性。这个时候我们需要绑定这个this,就是父组件里的this,让子组件使用父组件里的this,而不是自己的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)
.fontSize(20)
.finishedTask()
}else{
Text(this.item.name)
.fontSize(20)
}
Checkbox()
.select(this.item.finished)
.onChange(val => {
// 3.1更新当前的状态
this.item.finished = val
// 3.2 更新已完成的状态数量
// this.finishTask = this.tasks.filter(item => item.finished).length // 过滤,符合条件的留下
// this.handleTaskChange() // 这个函数由于我们封装的原因,已经不在我这个组件里了,但是我需要使用,可这个函数操作的是父组件里的变量,可我现在要使用它,我们可以让父组件传递给我,我定义一个变量接收
this.onTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
}