首页IT科技elementui代码生成器(记录–elementui源码学习之仿写一个el-button)

elementui代码生成器(记录–elementui源码学习之仿写一个el-button)

时间2025-06-20 18:28:30分类IT科技浏览7320
导读:这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助...

这里给大家分享我在网上总结出来的一些知识                ,希望对大家有所帮助

笔者这里是将悬浮的效果和按中的效果                      ,设置背景色越来越深                。这样的话       ,看着效果比较明显

主题按钮

所谓按钮的主题            ,就是添加不同的类名                       ,比如primary主题的按钮          ,就加上.primary类名              、success主题的按钮        ,就加上.success类名                      。然后使用动态class去添加即可(这里使用动态class的数组用法)       。如:

<button :class="[ myButton, type ]" />

变量type的值源自于使用按钮组件时                        ,传递进来的type参数

const typeArr = [ "", "primary", "success", "warning", "error", "text", "dangerText", ]; props:{ type: { // 按钮主题类型 type: String, validator(val) { return typeArr.includes(val); // 这里可以加一个校验函数              ,其实不加也行 }, }, }

然后给不同type值加上对应的样式即可            。如下:

// primary样式 .primary { background-color: #1867c0; color: #fff; } .primary:hover { background-color: #0854ac; } .primary:active { background-color: #033d7f; } // success样式 .success { background-color: #19be6b; color: #fff; } .success:hover { background-color: #0ea459; } .success:active { background-color: #008140; } // warning样式 .warning { background-color: #ffc163; color: #fff; } .warning:hover { background-color: #db952d; } .warning:active { background-color: #b97b1d; } // 等等type值样式...

按钮大小

按钮大小可以使用padding值的大小去控制    ,也可以直接使用zoom缩放做控制

这里使用动态style搭配计算属性的方式去控制                        ,如下代码:

// 不同的大小指定不同的缩放程度 const sizeObj = { small: 0.85, middle: 1, big: 1.2, }; props:{ size: String } <button :style="styleCal" /> computed: { styleCal() { return { zoom: sizeObj[this.size] // zoom缩放的值大小取决于传递进来的size值 } } }

按钮禁用

按钮禁用disable没啥好说的                  ,主要是要注意loading的时候,也要禁用掉                    ,loading加载的时候                      ,不允许用户再点击                       。

<button :disabled="disabled || loading" />

props:{ loading:Boolean }

这里注意一下    ,按钮禁用的样式也是通过动态class加上的                ,请往下看

按钮加载

注意加载时样式和加载按钮图标出来的时候                      ,将其他的图标给隐藏起来          。(同一时刻       ,只能有一个按钮图标            ,这样保证按钮加载时简洁一些)

<button :class="[ myButton, // 默认样式 disabled ? disabledBtn : , // 动态加上禁用按钮样式 loading ? loadingBtn : , // 动态加上loading加载中按钮样式 type, // 主题样式 ]" :disabled="disabled || loading" // 禁用时禁用                       ,加载时也禁用 > <i class="el-icon-loading" v-if="loading"></i> <!-- 使用传进来的图标          ,通过动态style控制图标和文字见的间隔        ,同一时刻下                        , 只能有一个图标出现              ,所以有loading图标了    ,就不能有别的图标了 --> <i :class="icon" :style="styleGap" v-if="icon && !loading"></i> <slot></slot> </button>

按钮的图标位置

默认从左往右排列(图标在左侧                       、文字在右侧)                        ,这里我们可以使用弹性盒的方向flexDirection属性                  ,来控制从左往右还是从右往左排列

<button :style="styleCal"/> styleCal() { // 控制缩放和指定默认圆角以及设置图标在文字左侧还是右侧 let styleObj = { zoom: sizeObj[this.size], borderRadius: "5px", flexDirection: this.rightIcon ? "row-reverse" : "row", }; return styleObj; },

图标按钮和单一文字按钮

这两个也很简单,

图标按钮注意加圆角的时机 单一文字按钮的样式要预留设置一份即可

然后动态控制一下即可

按钮组

按钮组注意事项:

首先将所有的按钮的圆角全部去掉(这样的话                    ,所有的按钮都是方方正正的按钮了) 然后单独给第一个按钮:first-of-type的左上角和左下角的圆角设置一下 然后再给最后一个按钮last-of-type的右上角和右下角的圆角设置一下 最后                      ,按钮组之间需要有间隔    ,这里使用border-right做分割线 最最后                ,再把最后一个按钮的右边框去掉即可                      ,如下css代码
// 附上按钮组样式 .myButtonGroup > .myButton { border-radius: unset !important; // 给所有的按钮都去掉圆角 border-right: 1px solid #fff; // 给按钮加上分隔线条 } // 第一个按钮左侧圆角 .myButtonGroup > .myButton:first-of-type { border-top-left-radius: 5px !important; border-bottom-left-radius: 5px !important; } // 最后一个按钮的右侧圆角 .myButtonGroup > .myButton:last-of-type { border-top-right-radius: 5px !important; border-bottom-right-radius: 5px !important; border-right: none; // 同时       ,清除最后一个按钮的右侧边框 }

代码

复制粘贴即可使用            ,如果道友觉得代码帮忙到了您                       ,欢迎给咱github仓库一个star哈?

myButton组件

<template> <button :style="styleCal" :class="[ myButton, disabled ? disabledBtn : , loading ? loadingBtn : , type, ]" :disabled="disabled || loading" @click="clickButton" > <i class="el-icon-loading iii" v-if="loading"></i> <!-- 使用传进来的图标          ,通过动态style控制图标和文字见的间隔        ,同一时刻下                        , 只能有一个图标出现              ,所以有loading图标了    ,就不能有别的图标了 --> <i :class="icon" :style="styleGap" v-if="icon && !loading"></i> <!-- 普通插槽有东西才去渲染 --> <span v-if="$slots.default"><slot></slot></span> </button> </template> <script> // 类型校验 const typeArr = [ "", "primary", "success", "warning", "error", "text", "dangerText", ]; const sizeArr = ["", "small", "middle", "big"]; // 大小检验 const sizeObj = { // 不同的大小指定不同的缩放程度 small: 0.85, middle: 1, big: 1.2, }; export default { name: "myButton", props: { disabled: Boolean, loading: Boolean, // loading时                        ,不可继续点击(继续点击不生效) rightIcon: Boolean, // 通过弹性盒的方向控制图标的位置 type: { type: String, validator(val) { return typeArr.includes(val); }, }, size: { type: String, validator(val) { return sizeArr.includes(val); }, }, icon: String, }, computed: { styleCal() { // 控制缩放和指定默认圆角以及设置图标在文字左侧还是右侧 let styleObj = { zoom: sizeObj[this.size], borderRadius: "5px", flexDirection: this.rightIcon ? "row-reverse" : "row", }; // 当有图标                  ,且没有文字的时候(或默认插槽没传),就让按钮变成圆形按钮 if ((this.icon && !this.$slots.default) || !this.$slots.default[0].text) { styleObj["borderRadius"] = "50%"; styleObj["padding"] = "12px"; } return styleObj; }, styleGap() { // 有图标                    ,有文字                      ,图标在左侧 if ( (this.icon && !this.$slots.default) || (this.$slots.default[0].text && !this.rightIcon) ) { return { paddingRight: "1px", }; } // 有图标    ,有文字                ,图标在右侧 if ( (this.icon && !this.$slots.default) || (this.$slots.default[0].text && this.rightIcon) ) { return { paddingLeft: "1px", }; } }, }, methods: { clickButton(e) { if (this.disabled) return; this.$emit("click", e); // 传出去                      ,便于使用 }, }, }; </script> <style lang=less scoped> /* 关于按钮的样式即写好几套样式       ,然后通过类型等各种参数去控制样式            ,最终实现对应效果 */ // 基础样式 .myButton { display: inline-flex; align-items: center; justify-content: center; white-space: nowrap; box-sizing: border-box; padding: 12px 16px; background-color: rgba(0, 0, 0, 0.1); color: #222; border: none; cursor: pointer; user-select: none; transition: all 0.3s; font-size: 14px; .iii { margin-right: 4px; } } .myButton:hover { background-color: rgba(0, 0, 0, 0.2); } .myButton:active { background-color: rgba(0, 0, 0, 0.3); } // primary样式 .primary { background-color: #1867c0; color: #fff; } .primary:hover { background-color: #0854ac; } .primary:active { background-color: #033d7f; } // success样式 .success { background-color: #19be6b; color: #fff; } .success:hover { background-color: #0ea459; } .success:active { background-color: #008140; } // warning样式 .warning { background-color: #ffc163; color: #fff; } .warning:hover { background-color: #db952d; } .warning:active { background-color: #b97b1d; } // error样式 .error { background-color: #ff5252; color: #fff; } .error:hover { background-color: #fd3030; } .error:active { background-color: #d50000; } // text样式 .text { background-color: unset; color: #409eff; padding: 2px 4px; } .text:hover { background-color: unset; opacity: 0.9; } .text:active { background-color: unset; opacity: 1; color: #1a7ada; } // dangerText样式 .dangerText { background-color: unset; color: #ff5252; padding: 2px 4px; } .dangerText:hover { background-color: unset; opacity: 0.9; } .dangerText:active { background-color: unset; opacity: 1; color: #d50000; } // 加载按钮样式 .loadingBtn { opacity: 0.6; pointer-events: none; // 值为none就没有hover和active效果了 } // disabled样式(注意样式的顺序) .disabledBtn { background-color: rgba(0, 0, 0, 0.12); color: #bbb; } .disabledBtn:hover { opacity: 1; cursor: not-allowed; background-color: rgba(0, 0, 0, 0.12); } .disabledBtn:active { color: #bbb; opacity: 1; background-color: rgba(0, 0, 0, 0.12); } // 附上按钮组样式 .myButtonGroup > .myButton { border-radius: unset !important; border-right: 1px solid #fff; } .myButtonGroup > .myButton:first-of-type { border-top-left-radius: 5px !important; border-bottom-left-radius: 5px !important; } .myButtonGroup > .myButton:last-of-type { border-top-right-radius: 5px !important; border-bottom-right-radius: 5px !important; border-right: none; } </style>

myButtonGroup组件

<template> <div class="myButtonGroup"> <slot></slot> </div> </template> <script> export default { name: "myButtonGroup", }; </script> <style> .myButtonGroup { display: inline-flex !important; align-items: center; } </style>

使用的时候

<template> <div> <h5>单个按钮</h5> <br /> <button @click="clickLoad">加载切换</button> <div class="btnBox"> <span class="btn" v-for="(item, index) of btnArr"> <my-button style="margin-right: 16px" :key="index" :type="item.type" :size="item.size" :disabled="item.disabled" :loading="item.loading" :icon="item.icon" :rightIcon="item.rightIcon" @click=" (e) => { clickBtn(item, e); } " >{{ item.name }}</my-button > </span> </div> <br /> <h5>按钮组</h5> <br /> <my-button-group> <my-button type="success" icon="el-icon-arrow-left">上一页</my-button> <my-button type="success" icon="el-icon-arrow-right" :rightIcon="true" >下一页</my-button > </my-button-group> <br /> <br /> <my-button-group> <my-button type="primary" icon="el-icon-user"></my-button> <my-button type="primary" icon="el-icon-view"></my-button> <my-button type="primary" icon="el-icon-star-off"></my-button> <my-button type="primary" icon="el-icon-chat-dot-square"></my-button> <my-button type="primary" icon="el-icon-share"></my-button> </my-button-group> </div> </template> <script> export default { name: "myButtonName", data() { return { loadingF: false, btnArr: [ { type: "", name: "默认按钮", }, { type: "primary", name: "primary", }, { type: "success", name: "success", }, { type: "warning", name: "warning", }, { type: "error", name: "error", }, { type: "primary", name: "size=small", size: "small", }, { type: "primary", name: "size=middle", size: "middle", }, { type: "primary", name: "size=big", size: "big", }, { type: "success", // 不管type什么类型                       ,只要禁用全部置灰 name: "disabled", disabled: true, }, { type: "primary", name: "等待加载", loading: false, }, { type: "success", name: "等待加载", loading: false, }, { type: "success", name: "icon", icon: "el-icon-star-on", }, { type: "success", name: "icon", icon: "el-icon-star-on", rightIcon: true, }, { type: "success", name: "", icon: "el-icon-edit", }, { type: "error", name: "", icon: "el-icon-delete", }, { type: "text", name: "纯text按钮", // loading: true, }, { type: "dangerText", name: "dangerText按钮", icon: "el-icon-delete-solid", }, { type: "text", name: "text禁用", disabled: true, }, ], }; }, methods: { clickLoad() { let lebel = this.btnArr[9].name; let newItem9 = { type: "primary", name: lebel == "等待加载" ? "加载中" : "等待加载", loading: lebel == "等待加载" ? true : false, }; this.$set(this.btnArr, 9, newItem9); let newItem10 = { type: "success", name: lebel == "等待加载" ? "加载中" : "等待加载", loading: lebel == "等待加载" ? true : false, }; this.$set(this.btnArr, 10, newItem10); }, // 注意这种写法          ,可接收多个参数 clickBtn(item, e) { console.log("clickBtn", item, e); }, }, }; </script> <style> .btnBox { width: 100%; box-sizing: border-box; padding: 24px 0; display: flex; align-items: flex-end; flex-wrap: wrap; } .btn { margin-bottom: 24px; } </style>

本文转载于:

https://juejin.cn/post/7182113902539309112

如果对您有所帮助        ,欢迎您点个关注                        ,我会定时更新技术文档              ,大家一起讨论学习    ,一起进步        。

声明:本站所有文章                        ,如无特殊说明或标注                  ,均为本站原创发布                        。任何个人或组织,在未征得本站同意时                    ,禁止复制        、盗用           、采集                      、发布本站内容到任何网站            、书籍等各类媒体平台              。如若本站内容侵犯了原著者的合法权益                      ,可联系我们进行处理    。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
win10版本20h2发布时间(Win10 20H2 Beta 预览版 19042.782正式推送(附更新内容))