# 如何解决容器类组件内容为空时margin的空间占用问题

#### 问题现象

容器类的组件设置了margin属性，当容器内容为空时margin依然会生效占用空间，如何实现当容器组件存在内容时，margin属性生效，容器组件内部为空时，margin不额外占用空间？

#### 效果预览

#### 背景知识

布局组件Row、Column、Stack、Flex、List、Swiper等均为可容纳子组件的容器组件。

*   margin设置组件的外边距属性，支持calc计算。
*   onAreaChange组件区域变化时触发该回调，可以获取组件区域的大小。

#### 解决方案

*   方案一：当容器组件**未主动设置宽高**且内部无组件时，其占据显示区域为0。使用onAreaChange获取容器组件的宽高，依据组件宽高来控制margin的值。
    
    根据组件宽高的数值来判断容器内部是否有内容，由于**计算精度可能导致的误差**，所以设置比较范围而不是判断是否为零。
    
*   方案二：根据业务逻辑自行判断容器内部是否为空，设置状态变量控制margin属性。
*   方案三：对于List、Swiper等组件，一般是依据数据源来展示，可根据数据源是否为空来设置margin属性。
    
    ```
    @Entry
    @Component
    struct PageMargin {
      @State dataSource: string[] = []; // 数据源
      @State content: boolean = false; // 自行保存容器内部状态
      @State rowWidth: number = 0; // 状态变量，保存容器组件的宽度
    
      build() {
        Column({ space: 16 }) {
          // 方案一
          Column() {
            // 当前Column中无组件
          }
          .onAreaChange((oldValue: Area, newValue: Area) => {
            this.rowWidth = newValue.width as number;
            console.info(`rowWidth: ${this.rowWidth}`);
          })
          .backgroundColor('#0a59f7')
          .margin(this.rowWidth <= 1 ? '0' : '20vp'); // 依据宽度控制margin
          // 方案二
          Column({ space: 16 }) {
            Button('toggle')
              .backgroundColor('#0a59f7')
              .onClick(() => {
                this.content = !this.content;
              });
            if (this.content) {
              Text('hello world');
            }
          }
          .margin(this.content === true ? '20vp' : '0');
    
          // 方案三
          Button('add dataSource')
            .backgroundColor('#0a59f7')
            .onClick(() => {
              this.dataSource.push('数据');
            });
          List() {
            ForEach(this.dataSource, (item: string, index: number) => {
              ListItem() {
                Text(item)
                  .onClick(() => {
                    console.info(`index: ${index}`);
                  });
              };
            }, (item: string, index) => item + index);
          }
          .padding(8)
          .backgroundColor('#f1f3f5')
          .borderRadius(5)
          .margin(this.dataSource.length === 0 ? '0' : '20vp');
        }
        .padding(16)
        .height('100%')
        .width('100%');
      }
    }
    ```