06.HarmonyOS-状态管理
1.State
class Person {
name: string
age: number
money: number
//参加加问号为可选参数
constructor(name: string, age: number, money?: number) {
this.name = name
this.age = age
this.money = money
}
}
@Extend(Text) function styleText(){
.margin({ top: 10 })
.backgroundColor("#ccc")
.padding({ top: 5, bottom: 5, left: 10, right: 10 })
.fontWeight(FontWeight.Bold)
.border({ width: 10, color: "#ccc", radius: 5 })
}
@Entry
@Component
struct StatePage {
@State name: string = "Tom"
@State age: number = 1
@State jack:Person=new Person("Jack",5,1000000)
@State rose:Person=new Person("Jack",5)
build() {
Column(){
Text(`姓名:${this.name} ,年龄: ${this.age}`)
.onClick(() => {
this.age++
this.name = "Tom"
})
.styleText()
Text(`姓名:${this.jack.name} ,年龄: ${this.jack.age} ,月薪: ${this.jack.money}`)
.onClick(() => {
this.jack.age++
this.jack.money++
this.jack.name = "Jack" ;
})
.styleText()
Text(`姓名:${this.rose.name} ,年龄: ${this.rose.age} ,月薪: ${this.rose.money}`)
.onClick(() => {
this.rose.age++
this.rose.name = "Jack" ;
})
.styleText()
}
.justifyContent(FlexAlign.Center)
.width("100%")
}
}
2.Prop、Link
//任务类
class Task {
static id: number = 1
//任务名称
name: string = `任务${Task.id++}`
//任务状态,是否完成
finished: boolean = false
}
//统一卡片样式
@Styles function card() {
.width("90%")
.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.任务进度卡片
TaskStatistics({totalTask:this.totalTask,finishTask:this.finishTask})
//2.新增任务按钮
//3.任务列表
//传引用使用$totalTask
TaskList({totalTask:$totalTask,finishTask:$finishTask,tasks:$tasks})
}
.backgroundColor("#f1f2f3")
}
}
//1.任务进度卡片
@Component
struct TaskStatistics{
//@Prop单项同步父复制一份给子组件,子组件修改不会影响父组件,不能初始化
@Prop finishTask: number
@Prop totalTask: number
build() {
Row() {
Text("任务进度")
.fontSize(30)
.fontWeight(FontWeight.Bold)
//堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。
Stack() {
//进度条组件,用于显示内容加载或操作处理等进度。
Progress({ value: this.finishTask, total: this.totalTask, type: ProgressType.Ring })
.width(100)
//使用Row为了让两个Text组件不要分这么开
Row() {
Text(this.finishTask.toString())
.fontSize(24)
.fontColor("#66D")
Text(" / " + this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({ top: 20, bottom: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
}
}
//2.新增任务按钮
//3.任务列表
@Component
struct TaskList{
//@Link双向同步传递的为地址,子组件修改父组件也跟着修改,不能初始化赋值
//总任务数量
@Link totalTask: number
//已完成任务数量
@Link finishTask: number
//任务数组
@Link tasks: Task[]
build() {
//子元素只能有一个根元素,所以需要放到一个容器里面去
Column(){
//2.新增任务按钮
Button("新增任务")
.width(200)
.onClick(() => {
//新增任务数据
this.tasks.push(new Task())
//更新任务总数
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) => {
//多选框改变赋值给任务完成状态
item.finished = val
//筛选选择的任务
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({ end: this.DeleteButton(index) })
}
)
}
.width("100%")
.padding({ top: 10 })
//高度其他元素(默认为0)占用完,剩下的都给我
.layoutWeight(1)
//内部元素居中
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button("删除")
.backgroundColor(Color.Red)
.margin({ left: 5 })
.onClick(() => {
//删除数组
this.tasks.splice(index, 1)
//更新总数和完成任务
this.handleTaskChange()
})
}
//更新总数和完成任务
handleTaskChange() {
//更新任务总数
this.totalTask = this.tasks.length
//筛选选择的任务
this.finishTask = this.tasks.filter((item) => {
return item.finished
}).length
}
}
3.Provide、Consume
//任务类
class Task {
static id: number = 1
//任务名称
name: string = `任务${Task.id++}`
//任务状态,是否完成
finished: boolean = false
}
//统一卡片样式
@Styles function card() {
.width("90%")
.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 StateInfo{
//总任务数量
totalTask: number = 0
//已完成任务数量
finishTask: number = 0
//任务数组
tasks: Task[] = []
}
@Entry
@Component
struct PropPage {
@Provide info: StateInfo = new StateInfo()
build() {
Column({ space: 10 }) {
//1.任务进度卡片
TaskStatistics()
//2.新增任务按钮
//3.任务列表
//传引用使用$totalTask
TaskList()
}
.backgroundColor("#f1f2f3")
}
}
//1.任务进度卡片
@Component
struct TaskStatistics{
//@Provide、@Consume可以跨组件使用不用传值
@Consume info: StateInfo
build() {
Row() {
Text("任务进度")
.fontSize(30)
.fontWeight(FontWeight.Bold)
//堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。
Stack() {
//进度条组件,用于显示内容加载或操作处理等进度。
Progress({ value: this.info.finishTask, total: this.info.totalTask, type: ProgressType.Ring })
.width(100)
//使用Row为了让两个Text组件不要分这么开
Row() {
Text(this.info.finishTask.toString())
.fontSize(24)
.fontColor("#66D")
Text(" / " + this.info.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({ top: 20, bottom: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
}
}
//2.新增任务按钮
//3.任务列表
@Component
struct TaskList{
//@Provide、@Consume可以跨组件使用不用传值
@Consume info: StateInfo
build() {
//子元素只能有一个根元素,所以需要放到一个容器里面去
Column(){
//2.新增任务按钮
Button("新增任务")
.width(200)
.onClick(() => {
//新增任务数据
this.info.tasks.push(new Task())
//更新任务总数
this.handleTaskChange()
})
//3.任务列表
List({ space: 10 }) {
ForEach(
this.info.tasks,
(item: Task, index) => {
ListItem() {
Row() {
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange((val) => {
//多选框改变赋值给任务完成状态
item.finished = val
//筛选选择的任务
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({ end: this.DeleteButton(index) })
}
)
}
.width("100%")
.padding({ top: 10 })
//高度其他元素(默认为0)占用完,剩下的都给我
.layoutWeight(1)
//内部元素居中
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button("删除")
.backgroundColor(Color.Red)
.margin({ left: 5 })
.onClick(() => {
//删除数组
this.info.tasks.splice(index, 1)
//更新总数和完成任务
this.handleTaskChange()
})
}
//更新总数和完成任务
handleTaskChange() {
//更新任务总数
this.info.totalTask = this.info.tasks.length
//筛选选择的任务
this.info.finishTask = this.info.tasks.filter((item) => {
return item.finished
}).length
}
}
4.ObjectLink、Observed
//任务类
//对象嵌套对象时,修改里面的对象页面不会渲染,所以需要@Observed标注在嵌套对象上@ObjectLink标注在使用的对象上,就可以正常渲染
@Observed
class Task {
static id: number = 1
//任务名称
name: string = `任务${Task.id++}`
//任务状态,是否完成
finished: boolean = false
}
//统一卡片样式
@Styles function card() {
.width("90%")
.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 StateInfo{
//总任务数量
totalTask: number = 0
//已完成任务数量
finishTask: number = 0
//任务数组
tasks: Task[] = []
}
@Entry
@Component
struct PropPage {
@Provide info: StateInfo = new StateInfo()
build() {
Column({ space: 10 }) {
//1.任务进度卡片
TaskStatistics()
//2.新增任务按钮
//3.任务列表
//传引用使用$totalTask
TaskList()
}
.backgroundColor("#f1f2f3")
}
}
//1.任务进度卡片
@Component
struct TaskStatistics{
//@Provide、@Consume可以跨组件使用不用传值
@Consume info: StateInfo
build() {
Row() {
Text("任务进度")
.fontSize(30)
.fontWeight(FontWeight.Bold)
//堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。
Stack() {
//进度条组件,用于显示内容加载或操作处理等进度。
Progress({ value: this.info.finishTask, total: this.info.totalTask, type: ProgressType.Ring })
.width(100)
//使用Row为了让两个Text组件不要分这么开
Row() {
Text(this.info.finishTask.toString())
.fontSize(24)
.fontColor("#66D")
Text(" / " + this.info.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({ top: 20, bottom: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
}
}
//2.新增任务按钮
//3.任务列表
@Component
struct TaskList{
//@Provide、@Consume可以跨组件使用不用传值
@Consume info: StateInfo
build() {
//子元素只能有一个根元素,所以需要放到一个容器里面去
Column(){
//2.新增任务按钮
Button("新增任务")
.width(200)
.onClick(() => {
//新增任务数据
this.info.tasks.push(new Task())
//更新任务总数
this.handleTaskChange()
})
//3.任务列表
List({ space: 10 }) {
ForEach(
this.info.tasks,
(item: Task, index) => {
ListItem() {
//方法传递时,方法里面有this关键字所以需要bind(this)把父类的绑定上去,不然就会使用子的this
TaskItem({item:item,onTaskChange:this.handleTaskChange.bind(this)})
}
.swipeAction({ end: this.DeleteButton(index) })
}
)
}
.width("100%")
.padding({ top: 10 })
//高度其他元素(默认为0)占用完,剩下的都给我
.layoutWeight(1)
//内部元素居中
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button("删除")
.backgroundColor(Color.Red)
.margin({ left: 5 })
.onClick(() => {
//删除数组
this.info.tasks.splice(index, 1)
//更新总数和完成任务
this.handleTaskChange()
})
}
//更新总数和完成任务
handleTaskChange() {
//更新任务总数
this.info.totalTask = this.info.tasks.length
//筛选选择的任务
this.info.finishTask = this.info.tasks.filter((item) => {
return item.finished
}).length
}
}
@Component
struct TaskItem{
//默认不能渲染数组里面的Task对象,使用@ObjectLink可以渲染嵌套对象
@ObjectLink item: Task
//方法传递
onTaskChange:()=> void
build() {
Row() {
//判断是否完成任务然后动态渲染
if(this.item.finished){
Text(this.item.name)
.finishedTask()
}else{
Text(this.item.name)
.fontSize(20)
}
Checkbox()
.select(this.item.finished)
.onChange((val) => {
//多选框改变赋值给任务完成状态
this.item.finished = val
//筛选选择的任务
//调用不到handleTaskChange方法,使用方法传递的方式调用
//this.handleTaskChange()
this.onTaskChange();
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
}
赞(1)
赏