当前位置:   article > 正文

ArkTS 状态管理@Prop、@Link_arkts prop

arkts prop

当父子组件之间需要数据同步的时候,可以使用@Prop和@Link装饰器。

实现的案例之中,代码时平铺直叙的,阅读性可理解性比较差。我们应改遵循组件化开发的思想。

在我们使用组件开发的时候,遇到数据同步问题的时候,@State状态是解决不了的。所以就要用到@Prop和@Link

我们可以将任务进度卡片封装为一个组件、将任务按钮和卡片列表封装为另外一个组件,来实现组件化的目的。 

任务进度卡片封装

我们先用@State尝试着封装任务进度卡片组件,然后再入口函数中使用。

  1. @Component
  2. struct TaskStatistics {
  3. @State finishTask: number = 0
  4. @State totalTask: number = 0
  5. build(){
  6. Row(){
  7. Text("任务进度")
  8. .fontSize(30)
  9. .fontWeight(FontWeight.Bold)
  10. Stack(){
  11. Progress({
  12. value:this.finishTask,
  13. total:this.totalTask,
  14. type:ProgressType.Ring
  15. })
  16. .width(100)
  17. Row(){
  18. Text(this.finishTask.toString())
  19. .fontSize(24)
  20. .fontColor('#36d')
  21. Text(' / ' +this.totalTask.toString())
  22. .fontSize(24)
  23. }
  24. }
  25. }
  26. .card()
  27. .margin({top:20,bottom:10})
  28. .justifyContent(FlexAlign.SpaceEvenly)
  29. }
  30. }

这样一来  PropPage组件就是父组件、TaskStatistics就是子组件。

其中的任务数量是由PropPage来维护的。所以我们需要从父亲向子传递数量属性,这时候我们会发现报错了,提示@State不支持之类的。

 这说明再父子传值的时候,@State状态已经不支持了。我们这个时候可以使用Prop和Link两个装时期。

Prop和Link装饰器

@Prop@Link
同步类型单向同步双向同步
允许装饰的变量类型

1.@Prop只支持string、number、boolean、enum类型

2.父组件对象类型、子组件对象属性

3.不可以是数组、any

1.父子类型一致:string、number、boolean、enum、object、class,以及他们的数组

2.数组中元素增、删、替换会引起刷新

3.嵌套类型以及数组中的对象属性无法触发视图更新。

初始化方式不允许子组件初始化父组件传递,禁止子组件初始化

@Prop是单向同步,父组件的改变会立即传递给子组件,但是子组件的修改不会影响父组件,他传递的是拷贝的值。

@LInk是双向同步,传递的是变量的引用,父亲和儿子使用的是一个变量,所以两方都会感知到变量的改变。

任务列表的封装

在封装任务列表的时候,要注意一些问题,比如说build函数下不能放入多个顶层,所以我们加一个Column容器,我们将按钮函数也加入。因为任务列表同任务进度是同步更新数据的,这里我们使用Link状态来完成。

  1. @Component
  2. struct TaskList {
  3. // 任务数量
  4. @State tasks: Task[] = []
  5. // 完成任务列表
  6. @Link finishTask: number
  7. // 所有的任务列表
  8. @Link totalTask: number
  9. // 通过过滤方法 更新已完成的任务数量
  10. handleTaskChange(){
  11. // 更新任务总数量
  12. this.totalTask = this.tasks.length
  13. // 已经完成的任务数量
  14. this.finishTask = this.tasks.filter(item => item.finished).length
  15. }
  16. build(){
  17. Column(){
  18. // 2.新增任务按钮
  19. Button('新增任务')
  20. .width(200)
  21. .onClick(()=>{
  22. // 1.新增任务
  23. this.tasks.push(new Task())
  24. // 2.更新任务数组
  25. this.totalTask = this.tasks.length
  26. })
  27. // 3.卡片列表
  28. List({space:10}){
  29. ForEach(
  30. this.tasks,
  31. (item: Task,index)=>{
  32. ListItem(){
  33. Row(){
  34. Text(item.name)
  35. .fontSize(20)
  36. Checkbox()
  37. .select(item.finished)
  38. .onChange(val=>{
  39. item.finished = val
  40. // 通过过滤方法 更新已完成的任务数量
  41. this.handleTaskChange()
  42. })
  43. }
  44. .card()
  45. .justifyContent(FlexAlign.SpaceBetween)
  46. }
  47. .swipeAction({end:this.DeleteButton(index)})
  48. }
  49. )
  50. }
  51. .width('100%')
  52. .layoutWeight(1)
  53. .alignListItem(ListItemAlign.Center)
  54. }
  55. }
  56. @Builder DeleteButton(index: number){
  57. Button("删除")
  58. .onClick(()=>{
  59. this.tasks.splice(index,1)
  60. this.handleTaskChange()
  61. })
  62. }
  63. }

我们在使用Link的时候,父类里面穿参数,需要使用$语法。 

我们会发现效果与我们最开始的效果是一样一样的。

验证数据类型

我们来验证一下@Prop和@Link的数据类型

我们来验证是否支持对象属性

1.创建一个统计信息的类 

  1. // 任务统计信息
  2. class StaticInfo{
  3. totalTask: number = 0
  4. finishTask: number = 0
  5. }

父组件中直接实例化 传值直接传入属性

2.子组件使用对象属性

我们在组件中使用对象属性来完成

  1. struct TaskList {
  2. // 任务数量
  3. @State tasks: Task[] = []
  4. @Link stat: StaticInfo
  5. // 通过过滤方法 更新已完成的任务数量
  6. handleTaskChange(){
  7. // 更新任务总数量
  8. this.stat.totalTask = this.tasks.length
  9. // 已经完成的任务数量
  10. this.stat.finishTask = this.tasks.filter(item => item.finished).length
  11. }

 

 @Provide和@Consume装饰器

@Provide和@Consume可以跨组件提供类似@State和@Link的双向同步功能。

@Provide和@Consume内部就能传递信息,不需要手写传递。 

如何使用

我们可以直接使用provide和consume,参数就不需要传递了,内部帮忙维护,代价是资源的损耗。所以我们在使用的时候优先考虑@State和@Link状态,遇到跨组件的时候,在使用@Provide和@Consume。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/288918
推荐阅读
相关标签
  

闽ICP备14008679号