文档管理中心

怎么解决自定义Span组件在NavDestination下无法显示问题

问题现象

包含Span组件的自定义组件,包含在Text组件下,让该Text组件置于NavDestination页面下,结果该自定义组件Span里的内容:Span自定义组件内容,没有显示。

问题效果预览:

背景知识

  • Text组件:Text是文本组件,通常用于展示用户视图,如显示文章的文字。
  • NavDestination组件:作为子页面的根容器,用于显示Navigation的内容区。

问题定位

  • Span内容不显示,依据文档排查该自定义子组件当前能力是否支持使用Span组件。
  • 在NavDestination页面下不显示,单独抽离出来在Page页面查看是否显示。

分析结论

  • Page会把全部的自定义组件都展开,Text组件解析到自定义组件下。
  • NavDestination机制下不会全部展开,自定义组件依赖后续组件内部自行展开,Text组件非容器组件,没有在解析子组件时做展开自定义操作。

修改建议

  1. Text不支持自定义组件,且Span组件作为Text、ContainerSpan组件的子组件,只能在这两个组件内使用,把Text和其下的Span抽离出来成单独的组件。
    @Component
    export struct pageOne {
      build() {
        NavDestination() {
          Column() {
            Text() {
              Span('Text直接包含的Span子组件1\n');
              Span('Text直接包含的Span子组件2\n');
              Span('Span自定义组件内容');
            };
          }.height('100%')
          .justifyContent(FlexAlign.Center);
        };
      }
    }
    
    @Entry
    @Component
    struct Index {
      pageInfos: NavPathStack = new NavPathStack();
    
      aboutToAppear(): void {
        console.info('nav index');
      }
    
      @Builder
      pages() {
        pageOne();
      }
    
      build() {
        Navigation(this.pageInfos) {
          Column() {
            Button('点击跳转到NavDestination页面')
              .onClick(() => {
                this.pageInfos.pushPath({ name: 'pageOne' });
              });
          }.height('100%')
          .justifyContent(FlexAlign.Center);
    
        }.navDestination(this.pages);
      }
    }

    效果预览:

  2. 如果Span组件是一组公共的特性,则可以通过@Builder装饰器把公共的部分抽取出来。
    @Component
    export struct pageOne {
      build() {
        NavDestination() {
          Column() {
            Text() {
              this.newLocalBuilder();
            };
          }.height('100%')
          .justifyContent(FlexAlign.Center);
        };
      }
    
      @Builder
      newLocalBuilder() {
        Span('Text直接包含的Span子组件1\n');
        Span('Text直接包含的Span子组件2\n');
        Span('Span自定义组件内容');
      }
    }
    
    @Entry
    @Component
    struct Index {
      pageInfos: NavPathStack = new NavPathStack();
    
      aboutToAppear(): void {
        console.info('nav index');
      }
    
      @Builder
      pages() {
        pageOne();
      }
    
      build() {
        Navigation(this.pageInfos) {
          Column() {
            Button('点击跳转到NavDestination页面')
              .onClick(() => {
                this.pageInfos.pushPath({ name: 'pageOne' });
              });
          }.height('100%')
          .justifyContent(FlexAlign.Center);
    
        }.navDestination(this.pages);
      }
    }

    效果预览:

  3. 如果需要使用自定义组件,应该选择支持自定义子组件的组件,比如Column组件。
    @Component
    export struct CustomSpan {
      aboutToAppear(): void {
        console.info('nav custom span');
      }
    
      build() {
        Text('Span自定义组件内容');
      }
    }
    
    @Component
    export struct pageOne {
      build() {
        NavDestination() {
          Column() {
            Text() {
              Span('Text直接包含的Span子组件1\n');
              Span('Text直接包含的Span子组件2\n');
            };
    
            CustomSpan();
          }.height('100%')
          .justifyContent(FlexAlign.Center);
        };
      }
    }
    
    @Entry
    @Component
    struct Index {
      pageInfos: NavPathStack = new NavPathStack();
    
      aboutToAppear(): void {
        console.info('nav index');
      }
    
      @Builder
      pages() {
        pageOne();
      }
    
      build() {
        Navigation(this.pageInfos) {
          Column() {
            Button('点击跳转到NavDestination页面')
              .onClick(() => {
                this.pageInfos.pushPath({ name: 'pageOne' });
              });
          }.height('100%')
          .justifyContent(FlexAlign.Center);
    
        }.navDestination(this.pages);
      }
    }

    效果预览:

总结

  • 组件下的子组件在使用时,首先要判断该组件支持的子组件类型,只有支持的子组件才能使用,才能保证所有场景都正确显示,比如Span组件只能在Text、ContainerSpan组件里使用。所以,最好按照组件规格说明来使用组件。
  • 自定义组件在使用时,要判断其所在父组件是否支持自定义组件,如果不支持,则不应该包含自定义组件。比如Text组件不支持自定义组件,就不能在Text的子组件里使用自定义组件。否则,系统不能保证所有场景显示都符合预期。
  • 自定义组件在使用时,也要判断自定义组件的最外层组件的使用范围。比如,自定义组件最外层是Span,而Span只能在Text和ContainerSpan里使用,如果用在Column里,则不会生效。
搜索
请输入您想要搜索的关键词