# 如何改变button外形_Vue3造轮子flavourui组件库之02制作Button组件

本文介绍了如何在Vue3中创建一个自定义Button组件,详细阐述了需求分析、API设计和编码过程。讨论了属性绑定细节,props与attrs的区别,并展示了如何让Button支持theme属性。同时,文章提到了UI库CSS注意事项,强调了最小影响原则。
摘要由CSDN通过智能技术生成

0. 最终效果

104eee1e2da766efb4370a8df1803f8e.gif

1. 第一步:需求分析

  • 参考一下别人的 Button,AntD,Bulma、Element、iView、Vuetify 等
  • 总结需求
    • 可以有不同的等级(level)
    • 可以是链接,可以是文字
    • 可以 click、focus、鼠标悬浮
    • 可以改变 size:大中小
    • 可以禁用(disabled)
    • 可以加载中(loading)

2. 第二步:API 设计

  • Button 组件怎么用
<button
  @click="?"
  @focus="?"
  @mouseover="?"theme="button or link or text"level="main or normal or minor"size="big normal small"disabledloading
>button>

3. 第三步:写代码

步骤
写 HTML
写 CSS
写 JS
测试
改写代码
再测试
再改写
再测试
再改写
再测试
再改写
……

4. 开始写代码

  • 在 lib 目录创建 Button.vue 组件
  • Button.vue, 按钮初步使用 slot 占位

  • ButtonDemo.vue
button 示例

示例1

你好


5. Vue3 属性绑定细节

  • 通过$attrs 将全部属性事件绑定到指定的某元素
// ButtonDemo.vue
button 示例

示例1

@click="onClick"
@focus="onClick"
@mouseover="onClick"
size="small"
>你好 >


  • Button.vue




  • 那如果我样将属性分别绑定到不同的子标签该如何做?



  • Vue 3 属性绑定小结
    • 默认所有属性都绑定到根元素
    • 使用 inheritAttrs: false 可以取消默认绑定
    • 使用 $attrs 或者 context.attrs 获取所有属性
    • 使用 v-bind="$attrs" 批量绑定属性
    • 使用 const {size, level, ...xxx} = context.attrs 将属性分开

6. props 和 attrs 的区别

  • props 要先声明才能取值,attrs 不用先声明
  • props 不包含事件,attrs 包含
  • props 没有声明的属性,会跑到 attrs 里
  • props 支持 string 以外的类型,attrs 只有 string 类型
  • ButtonDemo.vue
button 示例

示例1

@click="onClick"
@focus="onClick"
@mouseover="onClick"
size="small"
disabled
>你好 >


  • Button.vue



7. 如何让 Button 支持 theme 属性,theme 的值为 button/link/text

  • 解决 theme 为 undefined 的问题
    • 方式一,设置 theme 默认值


9. UI 库的 CSS 注意事项

  • 不能使用 scoped
    • 因为 data-v-xxx 中的 xxx 每次运行可能不同
    • 必须输出稳定不变的 class 选择器,方便使用者覆盖
    • 必须加前缀
  .button 不行,很容易被使用者覆盖
  .gulu-button 可以,不太容易被覆盖
  .theme-link 不行,很容易被使用者覆盖
  .gulu-theme-link 可以,不太容易被覆盖

10. CSS 最小影响原则

  • CSS 绝对不能影响库使用者
  • 在 lib 里面新建 gulu.scss
[class^="gulu-"],
[class*=" gulu-"]* {
//

//任何元素属性里面有个class是gulu-开头,或者class的第二个或者第三个含有gulu-
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 16px;
font-family: -apple-system, "Noto Sans", "Helvetica Neue", Helvetica,
"Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC",
"Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC",
"Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei",
"WenQuanYi Zen Hei", "ST Heiti", SimHei, "WenQuanYi Zen Hei Sharp",
sans-serif;
}
在 main.ts 引入,需要注意引入顺序
import "./lib/gulu.scss";
import "./index.scss";
import { createApp } from "vue";
// @ts-ignore
import App from "./App.vue";

11. 支持 theme 属性

&.gulu-theme-link {
  border-color: transparent;
  box-shadow: none;
  color: $blue;
  &:hover,
  &:focus {
    color: lighten($blue, 10%);
  }
}
&.gulu-theme-text {
  border-color: transparent;
  box-shadow: none;
  color: inherit;
  &:hover,
  &:focus {
    background: darken(white, 5%);
  }
}

12. 让 button 支持 size 属性

size 的值为 big / normal / small
// Button.vue



13. 让 button 支持 level 属性

level 的值为 main / normal / minor / danger



ButtonDemo
button 示例

示例1

你好你好你好你好

示例2

大大大普普通小小小
大大大普普通小小小
大大大普普通小小小

示例3

主要按钮普通按钮危险按钮 主要链接按钮普通链接按钮危险链接按钮 主要文字按钮普通文字按钮危险文字按钮


14. 让 button 支持 disabled

disabled 的值为 true / false用法

"true" />
Button.vue



ButtonDemo.vue

// 省略其他代码

示例4

禁用按钮禁用链接按钮禁用按钮


15. 让 button 支持 loading,loading 值为 true / false

ButtonDemo.vue

// 省略代码

示例5

加载中加载完毕


Button.vue



16. 知识点总结

Vue 属性继承 默认属性传给根元素inheritAttrs: false 禁用之v-bind="$attrs" 或 context.attrsprops V.S. attrs库的 CSS 要求 不能用 scoped每个 CSS 类要加前缀CSS 最小影响原则其他 如何做 loading 动画
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值