<template>
  <div
    class="gradient-background"
    :style="gradientStyle"
    :class="[gradientType, {'with-content': $slots.default}]"
  >
    <slot></slot>
  </div>
</template>

<script lang="ts">
  import { defineComponent, computed, PropType } from 'vue';

  // 渐变方向类型
  type GradientDirection =
    | 'to right'
    | 'to left'
    | 'to bottom'
    | 'to top'
    | 'to bottom right'
    | 'to top left'
    | 'to top right'
    | 'to bottom left'
    | string;

  // 渐变类型
  type GradientType = 'linear' | 'radial';

  export default defineComponent({
    name: 'GradientBackground',
    props: {
      // 渐变色数组
      colors: {
        type: Array as PropType<string[]>,
        default: () => ['#1890ff', '#36cfc9']
      },
      // 渐变方向
      direction: {
        type: String as PropType<GradientDirection>,
        default: 'to right'
      },
      // 渐变类型
      type: {
        type: String as PropType<GradientType>,
        default: 'linear'
      },
      // 是否启用动画效果
      animated: {
        type: Boolean,
        default: true
      },
      // 动画速度(秒)
      animationSpeed: {
        type: Number,
        default: 15
      },
      // 圆角半径
      radius: {
        type: [Number, String],
        default: 0
      }
    },
    setup(props) {
      // 计算渐变样式
      const gradientStyle = computed(() => {
        const borderRadius = typeof props.radius === 'number' ?
          `${props.radius}px` : props.radius;
        if (props.type === 'linear') {
          return {
            backgroundImage: `linear-gradient(${props.direction}, ${props.colors.join(', ')})`,
            animation: props.animated ? `gradientAnimation ${props.animationSpeed}s ease infinite` : 'none',
            borderRadius: borderRadius
          };
        } else {
          return {
            backgroundImage: `radial-gradient(circle, ${props.colors.join(', ')})`,
            animation: props.animated ? `gradientAnimation ${props.animationSpeed}s ease infinite` : 'none',
            borderRadius: borderRadius
          };
        }
      });

      return {
        gradientStyle
      };
    }
  });
</script>

<style scoped>
  .gradient-background {
    width: 100%;
    height: 100%;
    /*min-height: 200px;*/
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
    position: relative;
  }

  .gradient-background.with-content {
    padding: 2px;
  }

  .linear {
    background-size: 100% 100%;
  }

  .radial {
    background-size: 100% 100%;
  }

  /* 渐变动画 */
  @keyframes gradientAnimation {
    0% {
      background-position: 0% 50%;
    }
    50% {
      background-position: 100% 50%;
    }
    100% {
      background-position: 0% 50%;
    }
  }
</style>

引用组件

<GradientBackground
        :colors="['#81B337', '#96BF59']"
        radius="10px"
        direction="to right"
        class="demo-bg1"
      >
      h2>这是渐变背景上的内容</h2>
      <p>可以放置任何HTML或Vue组件</p>
</GradientBackground>
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐