Skip to content

按钮组件 第一步

css 样式

bash
   ├── src
    ├── components
      ├── chooseButton
       ├── src
    ├── index.vue
    ├── hooks
      ├── chooseButton
       ├── index.ts
    ├── styles
     ├── index.scss
     ├── chooseButton
     ├── chooseButton.scss
     ├── common
     ├── common.scss
     ├── isLoading.scss
     ├── iconfont.scss

styles/index.scss

scss
@use "./common/common.scss";
@use "./common/iconfont.scss";
@use "./common/isLoading.scss";
@use "./chooseButton/chooseButton.scss";

styles/common/iconfont.scss

scss
@font-face {
  font-family: "iconfont"; /* Project id 4684500 */
  src: url("//at.alicdn.com/t/c/font_4684500_jqcahkwqq0d.ttf?t=1750336704201")
    format("truetype");
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-ico:before {
  content: "\e646";
}

.icon-wushuju1:before {
  content: "\e69e";
}

.icon-wushuju3:before {
  content: "\e76d";
}

.icon-wushuju4:before {
  content: "\e636";
}

.icon-wushuju:before {
  content: "\eba4";
}

.icon-jinggao-yuan-F:before {
  content: "\e621";
}

.icon-tupian:before {
  content: "\e610";
}

.icon-a-wujiaoxingxingxing:before {
  content: "\e63c";
}

.icon-a-wujiaoxingxingxing-full-copy:before {
  content: "\101ce";
}

.icon-xingxing:before {
  content: "\e870";
}

.icon-buzhizuoye:before {
  content: "\e604";
}

.icon-zuoye1:before {
  content: "\e72c";
}

.icon-xinbaniconshangchuan-:before {
  content: "\e62e";
}

.icon-zuoye:before {
  content: "\e67d";
}

.icon-icon_zuoyexiangguan_zuoyedaan:before {
  content: "\e624";
}

.icon-locking:before {
  content: "\e65d";
}

.icon-shezhi:before {
  content: "\f383";
}

.icon-gou3:before {
  content: "\e716";
}

.icon-gouxuan:before {
  content: "\e605";
}

.icon-tijiao:before {
  content: "\e799";
}

.icon-close:before {
  content: "\e64a";
}

.icon-xiangpica:before {
  content: "\e7f1";
}

.icon-chehui:before {
  content: "\e76c";
}

.icon-qingchu:before {
  content: "\e60b";
}

.icon-xiazai:before {
  content: "\e752";
}

.icon-dayin:before {
  content: "\e616";
}

.icon-dayin1:before {
  content: "\e613";
}

.icon-jinzhichakan:before {
  content: "\e6bd";
}

.icon-yanjing:before {
  content: "\e6b4";
}

.icon-xiangji:before {
  content: "\e60f";
}

.icon-liuyan:before {
  content: "\e60e";
}

.icon-zan1:before {
  content: "\e7c0";
}

.icon-zan2:before {
  content: "\e60a";
}

.icon-dati:before {
  content: "\e620";
}

.icon-meiridati:before {
  content: "\e64d";
}

.icon-taolunB:before {
  content: "\101cd";
}

.icon-huabanfuben:before {
  content: "\e623";
}

.icon-fenxiang2:before {
  content: "\e622";
}

.icon-LOADING:before {
  content: "\e9ff";
}

.icon-refresh-full:before {
  content: "\e981";
}

.icon-shuangjiantou:before {
  content: "\e63d";
}

.icon-fasong:before {
  content: "\e612";
}

.icon-weixin:before {
  content: "\e614";
}

.icon-shouji:before {
  content: "\e615";
}

.icon-qianbi:before {
  content: "\e668";
}

.icon-chakan1:before {
  content: "\e664";
}

.icon-jinru:before {
  content: "\e650";
}

.icon-denghao:before {
  content: "\e694";
}

.icon-dacuo:before {
  content: "\e6e8";
}

.icon-dadui:before {
  content: "\e844";
}

.icon-tab-tingxie:before {
  content: "\e602";
}

.icon-pinyin1:before {
  content: "\e634";
}

.icon-cuotiben:before {
  content: "\e638";
}

.icon-cuotiben1:before {
  content: "\e764";
}

.icon-cuban2bihuajianpan:before {
  content: "\e82f";
}

.icon-huitui:before {
  content: "\e6bb";
}

.icon-fenxiang:before {
  content: "\e6e3";
}

.icon-home:before {
  content: "\e75f";
}

.icon-wenjianjia-L:before {
  content: "\e61f";
}

.icon-wode:before {
  content: "\10191";
}

.icon-zhuan:before {
  content: "\e686";
}

.icon-loading:before {
  content: "\e611";
}

.icon-a-shanchulajitong:before {
  content: "\e695";
}

.icon-jiantou2-copy:before {
  content: "\f418";
}

.icon-arrow-down-copy:before {
  content: "\f41b";
}

.icon-jiantou2:before {
  content: "\e601";
}

.icon-guanbi1:before {
  content: "\e603";
}

.icon-jia:before {
  content: "\e608";
}

.icon-guanbi:before {
  content: "\e609";
}

.icon-wenhao:before {
  content: "\e628";
}

.icon-gou:before {
  content: "\e6dc";
}

.icon-zanwushuju:before {
  content: "\e63f";
}

.icon-jiantuo:before {
  content: "\10192";
}

.icon-bofang:before {
  content: "\e607";
}

.icon-bofang1:before {
  content: "\f417";
}

.icon-dingshi:before {
  content: "\e600";
}

styles/common/common.scss

scss
button,
input,
optgroup,
select,
textarea {
  line-height: 1;
}

styles/common/isLoading.scss

scss
.is-loading-transition {
  animation: rotate 1.2s linear 0s infinite;
}
@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

styles/chooseButton/index.scss

scss
.Y-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 80px;
  padding: 0px 16px;
  height: 32px;
  border-radius: 12px;
  box-sizing: border-box;
  /* border: 2px solid #e2e6f1; */
  border-width: 2px;
  border-color: #e2e6f1;
  border-style: solid;
  background-color: #fff;
  font-size: 14px;
  color: #4d5059;
  cursor: pointer;
  word-break: keep-all;
  user-select: none;
  outline: none;
  transition: all 0.3s;
  column-gap: 4px;
  span {
    line-height: 1;
  }
  &:hover {
    background: #eaf0ff;
    border-color: #97b4ff;
    color: #3069ff;
  }
  &.is-round {
    border-radius: 100px;
  }
  &.is-disabled {
    background-color: #ebeef5;
    border-color: #ebeef5;
    color: #fff;
    cursor: not-allowed;
    span {
      color: #abb1bf;
    }
  }
  &.is-text {
    border: none;
    background-color: transparent;
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #7c808c;
      }
    }
  }
  &.is-link {
    height: auto;
    min-width: auto;
    padding: 0px;
    border: none;
    background-color: transparent;
    text-decoration: underline;
    text-underline-offset: 5px;
    text-decoration-color: #4d5059;
    span {
      color: #4d5059;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #7c808c;
        text-decoration-color: #7c808c;
      }
    }
  }
  &.is-block {
    width: 100%;
    display: flex;
  }
  &.is-border {
    background-color: transparent;
    span {
      color: #4d5059;
    }
    &.is-disabled,
    &:hover {
      background-color: white;
      border-color: #e2e6f1;
      span {
        color: #7c808c;
      }
    }
  }
  // 尺寸
  &.Y-button--size_large {
    height: 40px;
    font-size: 16px;
    // 圆形
    &.is-circle {
      padding: 0;
      width: 40px;
      min-width: 40px;
      border-radius: 100%;
      span {
        display: none;
      }
    }
  }
  &.Y-button--size_small {
    height: 24px;
    font-size: 12px;
    border-radius: 10px;
    // 圆形
    &.is-circle {
      padding: 0;
      width: 24px;
      min-width: 24px;
      border-radius: 100%;
      span {
        display: none;
      }
    }
  }
  // 圆形
  &.is-circle {
    padding: 0;
    width: 32px;
    min-width: 32px;
    border-radius: 100%;
    span {
      display: none;
    }
  }
  // 图标
  .Y-button__icon {
    font-size: 1em; // 字体1倍
  }
}

// 成功样式
.Y-button--success {
  background-color: #14cd70;
  border-color: #14cd70;
  span {
    color: #fff;
  }
  &:hover {
    background: #5bdc9b;
    border-color: #5bdc9b;
    color: #fff;
  }
  &.is-disabled {
    &,
    &:hover,
    &:focus {
      background-color: #8ae6b8;
      border-color: #8ae6b8;
      span {
        color: #fff;
      }
      cursor: not-allowed;
    }
  }
  &.is-text {
    border: none;
    background-color: transparent;
    span {
      color: #14cd70;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #8ae6b8;
      }
    }
  }
  &.is-link {
    text-decoration-color: #14cd70;
    span {
      color: #14cd70;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #8ae6b8;
        text-decoration-color: #8ae6b8;
      }
    }
  }
  &.is-border {
    background-color: transparent;
    span {
      color: #14cd70;
    }
    &.is-disabled {
      background-color: transparent;
      border-color: #14cd70;
      span {
        color: #14cd70;
      }
      &:hover {
        background-color: transparent;
        border-color: #14cd70;
        span {
          color: #14cd70;
        }
      }
    }
    &:hover {
      background-color: #14cd70;
      border-color: #14cd70;
      span {
        color: white;
      }
    }
  }
}

.Y-button--primary {
  background-color: #3069ff;
  border-color: #3069ff;
  color: #fff;
  span {
    color: #fff;
  }

  &:hover {
    background: #6e96ff;
    border-color: #6e96ff;
    color: #fff;
  }
  &.is-disabled {
    &,
    &:hover,
    &:focus {
      background-color: #98b4ff;
      border-color: #98b4ff;
      span {
        color: #fff;
      }
      cursor: not-allowed;
    }
  }
  &.is-text {
    border: none;
    background-color: transparent;
    span {
      color: #3069ff;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #6e96ff;
      }
    }
  }
  &.is-link {
    text-decoration-color: #3069ff;
    span {
      color: #3069ff;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #98b4ff;
        text-decoration-color: #98b4ff;
      }
    }
  }
  &.is-border {
    background-color: transparent;
    span {
      color: #3069ff;
    }
    &.is-disabled {
      background-color: transparent;
      border-color: #3069ff;
      span {
        color: #3069ff;
      }
      &:hover {
        background-color: transparent;
        border-color: #3069ff;
        span {
          color: #3069ff;
        }
      }
    }
    &:hover {
      background-color: #3069ff;
      border-color: #3069ff;
      span {
        color: white;
      }
    }
  }
}

.Y-button--warning {
  background-color: #ffa81a;
  border-color: #ffa81a;
  color: #fff;
  span {
    color: #fff;
  }

  &:hover {
    background: #ffc25f;
    border-color: #ffc25f;
    span {
      color: #fff;
    }
  }
  &.is-disabled {
    &,
    &:hover,
    &:focus {
      background-color: #ffd48d;
      border-color: #ffd48d;
      span {
        color: #fff;
      }
      cursor: not-allowed;
    }
  }
  &.is-text {
    border: none;
    background-color: transparent;
    span {
      color: #ffa81a;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #ffd48d;
      }
    }
  }
  &.is-link {
    text-decoration-color: #ffa81a;
    span {
      color: #ffa81a;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #ffd48d;
        text-decoration-color: #ffd48d;
      }
    }
  }
  &.is-border {
    background-color: transparent;
    span {
      color: #ffa81a;
    }
    &.is-disabled {
      background-color: transparent;
      border-color: #ffa81a;
      span {
        color: #ffa81a;
      }
      &:hover {
        background-color: transparent;
        border-color: #ffa81a;
        span {
          color: #ffa81a;
        }
      }
    }
    &:hover {
      background-color: #ffa81a;
      border-color: #ffa81a;
      span {
        color: white;
      }
    }
  }
}
.Y-button--danger {
  background-color: #ff4a5b;
  border-color: #ff4a5b;
  color: #fff;
  span {
    color: #fff;
  }

  &:hover {
    background: #ff808c;
    border-color: #ff808c;
    span {
      color: #fff;
    }
  }
  &.is-disabled {
    &,
    &:hover,
    &:focus {
      background-color: #ffa5ad;
      border-color: #ffa5ad;
      span {
        color: #fff;
      }
      cursor: not-allowed;
    }
  }
  &.is-text {
    border: none;
    background-color: transparent;
    span {
      color: #ff4a5b;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #ff808c;
      }
    }
  }
  &.is-link {
    text-decoration-color: #ff4a5b;
    span {
      color: #ff4a5b;
    }
    &.is-disabled,
    &:hover {
      background-color: transparent;
      span {
        color: #ffa5ad;
        text-decoration-color: #ffa5ad;
      }
    }
  }
  &.is-border {
    background-color: transparent;
    span {
      color: #ff4a5b;
    }
    &.is-disabled {
      background-color: transparent;
      border-color: #ff4a5b;
      span {
        color: #ff4a5b;
      }
      &:hover {
        background-color: transparent;
        border-color: #ff4a5b;
        span {
          color: #ff4a5b;
        }
      }
    }
    &:hover {
      background-color: #ff4a5b;
      border-color: #ff4a5b;
      span {
        color: white;
      }
    }
  }
}

流程三步

  1. 定义组件
  2. 写样式
  3. 调用

组件

  • ui/src/components/chooseButton/src/index.vue

  • 完成slot round disabled loading text link block border circle,图标 功能

vue
<template>
  <button
    :class="[
      ns.b(),
      ns.m(props.type),
      ns.m('size', buttonGroupSize),
      ns.is('round', props.round),
      ns.is('disabled', isLoading || props.disabled),
      ns.is('text', props.text),
      ns.is('link', props.link),
      ns.is('block', props.block),
      ns.is('border', props.border),
      ns.is('circle', props.circle),
    ]"
    :disabled="disabled || isLoading"
    @click="handleClick"
  >
    <!--loading效果-->
    <i v-if="isLoading" class="iconfont icon-LOADING is-loading-transition"></i>
    <!--前缀图标-->
    <i
      v-if="props.prefix && !isLoading"
      class="iconfont"
      :class="[ns.e('icon'), props.prefix]"
    ></i>
    <span>
      <slot></slot>
    </span>
    <!--后缀图标-->
    <i
      v-if="props.suffix"
      class="iconfont"
      :class="[ns.e('icon'), props.suffix]"
    ></i>
  </button>
</template>

<script setup lang="ts">
import { onMounted, computed, inject } from "vue";
import { useButton, useNamespace } from "../../../hooks/index";

const props = defineProps({
  type: {
    type: String,
    default: "",
  },
  text: {
    type: Boolean,
    default: false,
  },
  round: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  link: {
    type: Boolean,
    default: false,
  },
  block: {
    type: Boolean,
    default: false,
  },
  border: {
    type: Boolean,
    default: false,
  },
  size: {
    type: String,
    default: "", // 小small,中 就不用写 大large
  },
  circle: {
    type: Boolean,
    default: false,
  },
  // loading
  loading: {
    type: Boolean,
    default: false,
  },
  // 图标前面
  prefix: {
    type: String,
    default: "",
  },
  // 图标后面
  suffix: {
    type: String,
    default: "",
  },
  // loading事件 beforeChange 事件和click事件只会执行beforeChange事件
  beforeChange: {
    type: Function,
    default: undefined,
  },
});

const ns = useNamespace("button");

interface ButtonGroupContext {
  size?: {
    value: string;
  };
  // 其他可能存在的属性
}

const buttonGroup = inject<ButtonGroupContext>("buttonGroupKey");

const buttonGroupSize = computed(() => {
  return buttonGroup?.size?.value || props.size;
});
console.log("buttonGroup", buttonGroupSize);
// 自定义单击事件,防止beforeChange触发
const emit = defineEmits(["click"]);

const { handleClick, _loading } = useButton(props.beforeChange, emit);

const isLoading = computed(() => {
  return props.loading || _loading.value;
});
onMounted(() => {
  console.log("按钮组件挂载");
});
</script>

hooks

  • ui/src/hooks/chooseButton/index.ts
ts
import { ref } from "vue";

export const useButton = (cb: Function | undefined, emit: Function) => {
  // 名字
  const name = ref("点击我");
  // 私有loading,通过方法来确定loading状态
  const _loading = ref(false);
  // 点击事件
  const handleClick = (e: globalThis.Event) => {
    // 验证是否是方法
    // 因为绑定的是@click,所以这里需要判断是否是方法
    // 如果不加判断点击事件 和 beforeChange事件都会执行, 这样相当于执行2遍
    // 加上判断 只要传递过来beforeChange 方法, 就不会执行@click事件
    // 不传则执行@click事件
    const isFunction =
      Object.prototype.toString.call(cb) === "[object Function]";
    if (!isFunction) {
      // 如果两个全都有 它只执行beforeChange
      emit("click", e);
      return;
    } else {
      // 如果是方法,通过方法来确定loading状态
      _loading.value = true;
      if (cb) {
        cb()
          .then(() => {
            _loading.value = false;
            console.log("111");
          })
          .catch(() => {
            _loading.value = false;
            console.log("222");
          });
      }
    }
  };

  return {
    name,
    handleClick,
    _loading,
  };
};

调用组件库

vue
<template>
  <div class="pagecontent">
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      Button按钮
    </div>
    <YButton>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success">测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary">测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger">测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" round>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      Button按钮text
    </div>
    <YButton text>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" text>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" text>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" text>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" text>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      Button按钮disabled
    </div>
    <YButton disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      Button按钮text下面的disabled
    </div>
    <YButton text disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" text disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" text disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" text disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" text disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      Button按钮LINK
    </div>
    <YButton link>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" link>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" link>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" link>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" link>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      Button按钮LINK下面的disabled
    </div>
    <YButton link disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" link disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" link disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" link disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" link disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      按钮变成block
    </div>
    <YButton block>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" block>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" block>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" block>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" block>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      边框按钮
    </div>
    <YButton border>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" border>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" border>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" border>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" border>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      边框按钮disabled
    </div>
    <YButton border disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="primary" border disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="success" border disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="danger" border disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton type="warning" border disabled>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      尺寸大小size
    </div>
    <YButton size="large" type="primary">测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton size="small">测试1</YButton>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      circle圆形
    </div>
    <YButton circle type="primary">测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton circle>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton circle size="large">测试1</YButton>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      图标
    </div>
    <YButton type="primary" prefix="icon-fenxiang2" suffix="icon-fenxiang2"
      >测试1</YButton
    >
    <div style="width: 100%; height: 15px"></div>
    <YButton circle prefix="icon-LOADING" loading>测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <YButton size="large" loading>测试1</YButton>
    <YButton type="primary" prefix="icon-LOADING" loading>测试1</YButton>
    <YButton size="large">测试1</YButton>
    <div style="width: 100%; height: 15px"></div>
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      loading事件
    </div>
    <div style="width: 100%; height: 15px"></div>
    <YButton size="large" type="primary" :before-change="handleChange"
      >测试1</YButton
    >
    <div style="width: 100%; height: 15px"></div>
    <YButton
      size="large"
      type="primary"
      :before-change="handleChange"
      prefix="icon-fenxiang2"
      >测试1</YButton
    >
    <div
      style="width: 100%; height: 15px; background: #ccc; font-size: 15px; margin-bottom: 15px"
    >
      点击事件
    </div>
    <div style="width: 100%; height: 15px"></div>
    <YButton
      size="large"
      type="primary"
      :before-change="handleChange"
      @click="handleClick"
      >测试1</YButton
    >
    <div style="width: 100%; height: 15px"></div>
    <YButton size="large" type="primary" @click="handleClick">测试1</YButton>
  </div>
</template>

<script setup lang="ts">
// 模拟loading事件
const handleChange = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(true);
    }, 2000);
  });
};
// 模拟点击事件
const handleClick = () => {
  console.log("点击事件666");
};
</script>

<style lang="scss" scoped>
.pagecontent {
  padding: 15px 15px;
}
</style>