组件设计

140 阅读1分钟

组件设计

1、功能上拆分层次 2、尽量让组件原子化 3、容器组件(只管理数据)& UI组件(只显示视图),用redux的时候不必如此

state数据结构设计

1、用数据描述所有的内容 2、数据要结构化、易于程序操作(遍历、查找) 3、数据要可扩展,以便增加新的功能

在element组件的基础上包一层

// 使用
<os-empty description="暂无数据" :image-size="200" :image="imageUrl">
    // 放到默认插槽里
    <sc-button type="primary">按钮</sc-button>
    // 放到具名插槽description里
    <template v-slot:description >111111</template>
</os-empty>
// 组件包一层

<template>
    <div>
      <sc-empty v-bind="$attrs">
        // 默认插槽 这里的东西还会传到sc-empty的默认插槽里
        <slot></slot>
        // 这里的东西会传到sc-empty具名插槽description里
        <template v-slot:description ><slot v-if="$slots.description"  name="description"> </slot></template>
        </slot>
      </sc-empty>
    </div>
  </template>
  <script>
  export default {
    name: 'OsEmpty',
    prop: {
        imageSize: {
            type: Number,
            default: 40,
        },
        image: {
            type: String,
            default: require('@/common/os-assets/componentsImages/empty.png'),
        },
    },
    data() {
        return {
        }
    }
  }
  </script>
  <style lang="scss" scoped>
  </style>


直接在element的组件的源码上进行修改

// 使用
<os-empty description="暂无数据" image-size="2.4rem" :image="imageUrl">
    <sc-button type="primary">按钮</sc-button>
</os-empty>
// 组件
<template>
    <div class="os-empty">
      <div class="os-empty__image" :style="imageStyle">
        <img v-if="image" :src="image" ondragstart="return false">
        <slot v-else name="image">
            <img src="@/common/os-assets/componentsImages/empty.png" ondragstart="return false">
        </slot>
      </div>
      <div class="os-empty__description">
        <slot v-if="$slots.description" name="description"></slot>
        <p v-else>{{ emptyDescription }}</p>
      </div>
      <div v-if="$slots.default" class="os-empty__bottom">
        <slot></slot>
      </div>
    </div>
</template>
  
<script>
  
  export default {
    name: 'OsEmpty',
    props: {
      image: {
        type: String,
        default: ''
      },
      imageSize:  {
        type: String,
        default: ''
      },
      description: {
        type: String,
        default: ''
      }
    },
    computed: {
      emptyDescription() {
        return this.description;
      },
      imageStyle() {
        return {
          width: this.imageSize ? this.imageSize : ''
        };
      }
    },
    data() {
        return {}
    }
  };
</script>

<style lang="scss" scoped>
.os-empty {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  text-align: center;
  box-sizing: border-box;
  padding: 0.4rem 0;

  .os-empty__image {
    width: 2.4rem;

    img {
      user-select: none;
      width: 100%;
      height: 100%;
      vertical-align: top;
      object-fit: contain;
    }
  }

  .os-empty__description {
    margin-top: 0.24rem;

    p {
      margin: 0;
      font-size: 0.18rem;
      color: rgba(255, 255, 255, 0.6);
    }
  }

  .os-empty__bottom {
    margin-top: 0.24rem;
  }
}

</style>