| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <template>
- <div
- class="skeleton space-y"
- :class="{ animated: animate }"
- :style="`--color:${bgColor}`"
- v-if="loading"
- >
- <div
- class="skeleton-row space-x"
- :class="[styleMaps[item.align || 'left'], styleMaps[item.verticalAlign || 'middle']]"
- v-for="(item, index) in rowList"
- :style="item.style || {}"
- :key="index"
- >
- <div
- class="skeleton-row-item space-y"
- v-for="(item1, index1) in item.colItems"
- :class="[item1.shape || '', item1.childRowItems ? 'no-height' : '']"
- :key="index1"
- :style="item1.style || { width: `${100 / item.colItems}%` }"
- >
- <template v-if="item1.childRowItems">
- <div
- class="skeleton-col-item"
- v-for="(item2, index2) in item1.childRowItems"
- :class="item2.shape || ''"
- :key="index2"
- :style="item2.style || {}"
- ></div>
- </template>
- </div>
- </div>
- </div>
- <div v-else><slot></slot></div>
- </template>
- <script>
- export default {
- name: 'Skeleton',
- props: {
- bgColor: {
- type: String,
- default: '#f1f1f1',
- },
- rowList: {
- type: Array,
- default: () => config.common.skeletons,
- },
- loading: {
- type: Boolean,
- default: true,
- },
- animate: {
- type: Boolean,
- default: true,
- },
- scale: {
- type: String,
- },
- },
- data() {
- return {
- styleMaps: {
- left: 'justify-start',
- center: 'justify-center',
- right: 'justify-end',
- between: 'justify-between',
- around: 'justify-around',
- top: 'items-start',
- middle: 'items-center',
- bottom: 'items-end',
- },
- }
- },
- }
- </script>
- <style lang="scss" scoped>
- .skeleton {
- width: 100%;
- &.animated {
- animation: blink 1.2s ease-in-out infinite;
- }
- & div {
- box-sizing: border-box;
- }
- }
- .skeleton-row {
- display: flex;
- align-content: space-between;
- width: 100%;
- }
- .skeleton-row-item,
- .skeleton-col-item {
- // display: inline-block;
- height: $p-spac * 2;
- border-radius: 6rpx;
- &:not(.no-height) {
- background: var(--color);
- }
- &.round {
- border-radius: 999px;
- }
- &.circle {
- border-radius: 50%;
- }
- &.no-height {
- height: auto;
- }
- }
- .skeleton-col-item:last-child {
- margin: 0;
- }
- .space-x > div,
- .space-x > view {
- --tw-space-x-reverse: 0;
- margin-right: calc($p-spacd2 * var(--tw-space-x-reverse));
- margin-left: calc($p-spacd2 * calc(1 - var(--tw-space-x-reverse)));
- &:first-child {
- margin: 0;
- }
- }
- .space-y > div,
- .space-y > view {
- --tw-space-y-reverse: 0;
- margin-top: calc($p-spacd2 * var(--tw-space-y-reverse));
- margin-bottom: calc($p-spacd2 * calc(1 - var(--tw-space-y-reverse)));
- }
- .justify-start {
- justify-content: flex-start;
- }
- .justify-end {
- justify-content: flex-end;
- }
- .justify-center {
- justify-content: center;
- }
- .justify-between {
- justify-content: space-between;
- }
- .justify-around {
- justify-content: space-around;
- }
- .items-start {
- align-items: flex-start;
- }
- .items-end {
- align-items: flex-end;
- }
- .items-center {
- align-items: center;
- }
- @keyframes blink {
- 0% {
- opacity: 1;
- }
- 50% {
- opacity: 0.6;
- }
- 100% {
- opacity: 1;
- }
- }
- </style>
|