前端学习案例-手动封装element-ui里面的button组件

简介: 前端学习案例-手动封装element-ui里面的button组件
首先我们知道vue里面包含有父子组件
但是你知道如果要进行一个element的手动组件封装
怎么封装吗
1首先第一步
首先我们建立一个组件
最好设置在一个文件目录下比如components
只是一个普通的组件
叫做OneButton.vue
        <template>
           <button class="one-button">
            按钮组件
           </button>
         </template>
         <script>
         export default {
           name: 'oneButton'
         }
     </script>
         <style lang="scss">
     </style>要想使用该组件
就需要进行全局注册
就是在main.js里面注册了
     import Vue from 'vue'
         import App from './App.vue'
         // 第一步:导入button组件
         import OneButton from './components/button.vue'
         Vue.config.productionTip = false
         // 第二步:注册组件,设置(组件名,组件)
         Vue.component(OneButton.name, OneButton)
         new Vue({
           render: h => h(App)
         }).$mount('#app')注册完成以后就可以进行使用了
    <template>
       <div id="app">
         <one-button>按钮</one-button>
       </div>
     </template>
     <script>
     export default {
       name: 'App',
       components: {}
     }
     </script>
     <style lang="scss">
     </style>到这里
我们可以看到 就会显示一个普通按钮了
但是吧 这样的封装过于简单
能不能实现更加复杂的操作呢
于是
我们需要封装一个有element-ui风格的组件
好 那我们继续实现
我们先让文字可以自由的输入
那就要利用插槽了
     <template>
           <button class="one-button">
            <span><slot></slot></span>
           </button>
         </template>我们的文件需要做以上处理
     <template>
           <div>
             <one-button>歌谣</one-button>
             <one-button>帅气</one-button>
             <one-button>关注我</one-button>
           </div>
         </template>加上基本样式
     <style lang="scss">
           .one-button{
             display: inline-block;
             line-height: 1;
             white-space: nowrap;
             cursor: pointer;
             background: #ffffff;
             border: 1px solid #dcdfe6;
             color: #606266;
             -webkit-appearance: none;
             text-align: center;
             box-sizing: border-box;
             outline: none;
             margin: 0;
             transition: 0.1s;
             font-weight: 500;
             //禁止元素的文字被选中
             -moz-user-select: none;
             -webkit-user-select: none;
             -moz-user-select: none;
             -ms-user-select: none;
             padding: 12px 20px;
             font-size: 14px;
             border-radius: 4px;
             &:hover,
             &:hover{
               color: #409eff;
               border-color: #c6e2ff;
               background-color: #ecf5ff;
             }
           }
         </style>这样文字的效果就实现了
到了这里 你又想element里面可以控制type属性控制按钮样式
怎么可以实现呢
父元素传递type值
        <template>
           <div id="app">
             <div class="row">
             <one-button>按钮</one-button>
             <one-button type="primary">primary按钮</one-button>
             <one-button type="success">success按钮</one-button>
             <one-button type="info">info按钮</one-button>
             <one-button type="danger">danger按钮</one-button>
             <one-button type="warning">warning按钮</one-button>
             </div>
           </div>
         </template>子元素接收当然props了
     export default {
           name: 'oneButton',
           // 此时对props进行校验,值接收string类型的type值
           props: {
             type:{
               type: String,
               // 设置默认值:如果不传值,那么使用default
               default: 'default'
             }
           },
           created () {
             console.log(this.type)//defalut primary success info danger warning
           }
         }做过处理以后根据type就可以实现数据的操作了
动态绑定样式
      <template>
           <button class="one-button" :class="`one-button-${type}`">
            <span><slot></slot></span>
           </button>
         </template>最后定义好样式
      .one-button-primary{
           color:#fff;
           background-color: #409eff;
           border-color: #409eff;
           &:hover,
           &:focus{
             background: #66b1ff;
             background-color: #66b1ff;
             color: #fff;
             }
           }
           .one-button-success{
           color:#fff;
           background-color: #67c23a;
           border-color: #67c23a;
           &:hover,
           &:focus{
             background: #85ce61;
             background-color: #85ce61;
             color: #fff;
             }
           }
           .one-button-info{
           color:#fff;
           background-color: #909399;
           border-color: #909399;
           &:hover,
           &:focus{
             background: #a6a9ad;
             background-color: #a6a9ad;
             color: #fff;
             }
           }
           .one-button-warning{
           color:#fff;
           background-color: #e6a23c;
           border-color: #e6a23c;
           &:hover,
           &:focus{
             background: #ebb563;
             background-color: #ebb563;
             color: #fff;
             }
           }
           .one-button-danger{
           color:#fff;
           background-color: #f56c6c;
           border-color: #f56c6c;
           &:hover,
           &:focus{
             background: #f78989;
             background-color: #f78989;
             color: #fff;
             }
           }运行
nice呀 有没有
这个时候你可能会想
如果设置plain属性怎么设置呢
和type类型相同,我们只要将样式先设置好,然后通过父组件传递过来的值进行判断,就可以设置plain属性了。
    和type类型相同,我们只要将样式先设置好,然后通过父组件传递过来的值进行判断,就可以设置plain属性了。
     第一步:父组件组件传递plain值
         <template>
           <div id="app">
             <div class="row">
             <one-button plain>按钮</one-button>
             <one-button plain type="primary">primary按钮</one-button>
             <one-button plain type="success">success按钮</one-button>
             <one-button plain type="info">info按钮</one-button>
             <one-button plain type="danger">danger按钮</one-button>
             <one-button plain type="warning">warning按钮</one-button>
             </div>
           </div>
         </template>
     第二步:子组件接收负组件传递的数据,同样进行props校验,并且设置默认值为false
           props: {
             plain: {
               type: Boolean,
               default: false
             }
           }
     第三步:通过绑定类名的方法动态控制样式,由于plain类型是布尔值,所以在类型中我们使用对象的形式来控制样式
         <template>
           <button class="one-button" :class="[`one-button-${type}`,{
             'is-plain':plain
           }]">
            <span><slot></slot></span>
           </button>
         </template>
     第四步:设置不同类型的样式,由于plain类型是以对象的形式在类中定义的,所以使用获取属性的方法定义样式
         // 朴素按钮样式
         .one-button.is-plain{
           &:hover,
           &:focus{
             background: #fff;
             border-color: #489eff;
             color: #409eff;
           }
         }
         .one-button-primary.is-plain{
           color: #409eff;
           background: #ecf5ff;
           &:hover,
           &:focus{
             background: #409eff;
             border-color: #409eff;
             color: #fff;
           }
         }
         .one-button-success.is-plain{
           color: #67c23a;
           background: #c2e7b0;
           &:hover,
           &:focus{
             background: #67c23a;
             border-color: #67c23a;
             color: #fff;
           }
         }
         .one-button-info.is-plain{
           color: #909399;
           background: #d3d4d6;
           &:hover,
           &:focus{
             background: #909399;
             border-color: #909399;
             color: #fff;
           }
         }
         .one-button-warning.is-plain{
           color: #e6a23c;
           background: #f5dab1;
           &:hover,
           &:focus{
             background: #e6a23c;
             border-color: #e6a23c;
             color: #fff;
           }
         }
         .one-button-danger.is-plain{
           color: #f56c6c;
           background: #fbc4c4;
           &:hover,
           &:focus{
             background: #f56c6c;
             border-color: #f56c6c;
             color: #fff;
           }
         }nice呀 有没有
round属性也是一样
    button组件的round属性
     设置round属性和之前的相似,只要在组件中定义好了样式,动态获取属性值即可。
     获取属性值:
             round: {
               type: Boolean,
               default: false
             }
     round样式:
         .one-button.is-round{
           border-radius: 20px;
           padding: 12px 23px;
         }看看效果
nice有没有
到这里
我们看看字体图标怎么实现
字体图标也是要引入的
    第一步:在main.js中引入字体图标
     import './assets/fonts/iconfont.css'
     第二步:将下载的字体图标css文件中的类名做修改,我将icon全部改为了one-icon,并且将初始的iconfont类改为了[class*='one-icon'],当类名中有one-icon时使用,如下
         [class*='one-icon'] {
           font-family: "iconfont" !important;
           font-size: 16px;
           font-style: normal;
           -webkit-font-smoothing: antialiased;
           -moz-osx-font-smoothing: grayscale;
         }
         .one-icon-bluetoothoff:before {
           content: "\e697";
         }
     第三步:父组件传递图标名,子组件接收并且放到图标中
     父组件传值:
             <div class="row">
               <one-button icon="bluetoothon"></one-button>
               <one-button type="primary" icon="camera">照相机</one-button>
               <one-button type="success" icon="course"></one-button>
               <one-button type="info" icon="bluetooth_link"></one-button>
               <one-button type="danger" icon="addto"></one-button>
               <one-button type="warning" icon="audio"></one-button>
             </div>
     子组件接收:
             icon: {
               type: String,
               default: ''
             }
     使用接收到的字体图标。在没有传入icon时隐藏<i>标签,在slot插槽没有传入值时,不显示<span>标签
         <template>
           <button class="one-button" :class="[`one-button-${type}`,{
             'is-plain':plain,
             'is-round':round,
             'is-circle':circle,
           }]">
           <i v-if="icon" :class="`one-icon-${icon}`"></i>
           <!-- 如果没传入文本插槽,则不显示span内容 -->
            <span v-if="$slots.default"><slot></slot></span>
           </button>
         </template>
     第四步:设置icon配套样式,使图标和文字之间有一定间隔
         .one-button [class*=one-icon-]+span{
           margin-left: 5px;
         }
      查看效果
nice有没有
到这里
我们想一想element里面还有点击事件怎么实现
    button组件中的点击事件
     我们在使用组件时,直接给组件定义事件是不会被触发的。我们需要在组件中定义一个点击事件,这个点击事件不进行其他操作,只出发父组件中的点击事件。
     组件中的定义点击事件:
         <template>
           <button class="one-button" :class="[`one-button-${type}`,{
             'is-plain':plain,
             'is-round':round,
             'is-circle':circle,
           }]"
           @click="handleClick"
           >
           <i v-if="icon" :class="`one-icon-${icon}`"></i>
           <!-- 如果没传入文本插槽,则不显示span内容 -->
            <span v-if="$slots.default"><slot></slot></span>
           </button>
         </template>
      定义一个点击事件,这个点击事件的作用是调用父组件中的点击事件,并且回调
           methods: {
             handleClick (e) {
               this.$emit('click', e)
             }
           }
     父组件在使用时定义自己的点击事件,其本质是子组件中的点击事件触发父组件中的点击事件。
         <div class="row">
           <one-button @click="getInfo">按钮</one-button>
         </div>
           methods: {
             getInfo () {
               console.log('获取信息!!')//获取信息!!
             }
           }就很nice
按钮中会设置是否禁用
我们可以通过父子传值
给子组件设置样式实现
    button组件中的disabled属性
     和之前相似,只要父子组件传值并且动态获取这个值并且赋给disabled属性,并且设置一个disabled样式即可。
         <div class="row">
           <one-button @click="getInfo" disabled>按钮</one-button>
         </div>
         <template>
           <button class="one-button" :class="[`one-button-${type}`,{
             'is-plain':plain,
             'is-round':round,
             'is-circle':circle,
             'is-disabled':disabled
           }]"
           @click="handleClick"
           :disabled="disabled"
           >
           <i v-if="icon" :class="`one-icon-${icon}`"></i>
            <span v-if="$slots.default"><slot></slot></span>
           </button>
         </template>
             disabled: {
               type: Boolean,
               default: false
             }
      disabled样式:
         .one-button.is-disabled{
            cursor: no-drop;
         }至此 element中的button组件就封装完成了 是不是很nice
下次有时间继续封转其他的
看看封装的总代码
    <template>
       <button class="one-button" :class="[`one-button-${type}`,{
         'is-plain':plain,
         'is-round':round,
         'is-circle':circle,
         'is-disabled':disabled
       }]"
       @click="handleClick"
       :disabled="disabled"
       >
       <i v-if="icon" :class="`one-icon-${icon}`"></i>
       <!-- 如果没传入文本插槽,则不显示span内容 -->
        <span v-if="$slots.default"><slot></slot></span>
       </button>
     </template>
     <script>
     export default {
       name: 'oneButton',
       // 此时对props进行校验,值接收string类型的type值
       props: {
         type: {
           type: String,
           // 设置默认值:如果不传值,那么使用default
           default: 'defalut'
         },
         plain: {
           type: Boolean,
           default: false
         },
         round: {
           type: Boolean,
           default: false
         },
         circle: {
           type: Boolean,
           default: false
         },
         icon: {
           type: String,
           default: ''
         },
         disabled: {
           type: Boolean,
           default: false
         }
       },
       created () {
         // 显示所有插槽
         // console.log(this.$slots)
       },
       methods: {
         // 定义一个点击事件,这个点击事件的作用是调用父组件中的点击事件,并且回调
         handleClick (e) {
           this.$emit('click', e)
         }
       }
     }
     </script>
     <style lang="scss" scoped>
       .one-button{
         display: inline-block;
         line-height: 1;
         white-space: nowrap;
         cursor: pointer;
         background: #ffffff;
         border: 1px solid #dcdfe6;
         color: #606266;
         -webkit-appearance: none;
         text-align: center;
         box-sizing: border-box;
         outline: none;
         margin: 0;
         transition: 0.1s;
         font-weight: 500;
         //禁止元素的文字被选中
         -moz-user-select: none;
         -webkit-user-select: none;
         -moz-user-select: none;
         -ms-user-select: none;
         padding: 12px 20px;
         font-size: 14px;
         border-radius: 4px;
         &:hover,
         &:focus{
           color: #409eff;
           border-color: #c6e2ff;
           background-color: #ecf5ff;
         }
       }
     .one-button-primary{
       color:#fff;
       background-color: #409eff;
       border-color: #409eff;
       &:hover,
       &:focus{
         background: #66b1ff;
         background-color: #66b1ff;
         color: #fff;
         }
       }
       .one-button-success{
       color:#fff;
       background-color: #67c23a;
       border-color: #67c23a;
       &:hover,
       &:focus{
         background: #85ce61;
         background-color: #85ce61;
         color: #fff;
         }
       }
       .one-button-info{
       color:#fff;
       background-color: #909399;
       border-color: #909399;
       &:hover,
       &:focus{
         background: #a6a9ad;
         background-color: #a6a9ad;
         color: #fff;
         }
       }
       .one-button-warning{
       color:#fff;
       background-color: #e6a23c;
       border-color: #e6a23c;
       &:hover,
       &:focus{
         background: #ebb563;
         background-color: #ebb563;
         color: #fff;
         }
       }
       .one-button-danger{
       color:#fff;
       background-color: #f56c6c;
       border-color: #f56c6c;
       &:hover,
       &:focus{
         background: #f78989;
         background-color: #f78989;
         color: #fff;
         }
       }
     // 朴素按钮样式
     .one-button.is-plain{
       &:hover,
       &:focus{
         background: #fff;
         border-color: #489eff;
         color: #409eff;
       }
     }
     .one-button-primary.is-plain{
       color: #409eff;
       background: #ecf5ff;
       &:hover,
       &:focus{
         background: #409eff;
         border-color: #409eff;
         color: #fff;
       }
     }
     .one-button-success.is-plain{
       color: #67c23a;
       background: #c2e7b0;
       &:hover,
       &:focus{
         background: #67c23a;
         border-color: #67c23a;
         color: #fff;
       }
     }
     .one-button-info.is-plain{
       color: #909399;
       background: #d3d4d6;
       &:hover,
       &:focus{
         background: #909399;
         border-color: #909399;
         color: #fff;
       }
     }
     .one-button-warning.is-plain{
       color: #e6a23c;
       background: #f5dab1;
       &:hover,
       &:focus{
         background: #e6a23c;
         border-color: #e6a23c;
         color: #fff;
       }
     }
     .one-button-danger.is-plain{
       color: #f56c6c;
       background: #fbc4c4;
       &:hover,
       &:focus{
         background: #f56c6c;
         border-color: #f56c6c;
         color: #fff;
       }
     }
     // round属性
     .one-button.is-round{
       border-radius: 20px;
       padding: 12px 23px;
     }
     // circle属性
     .one-button.is-circle{
       border-radius: 50%;
       padding: 12px;
     }
     // icon配套样式
     .one-button [class*=one-icon-]+span{
       margin-left: 5px;
     }
     // disabled属性
     .one-button.is-disabled{
        cursor: no-drop;
     }
     </style>
相关文章
|
22天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
161 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
8天前
|
JavaScript 数据安全/隐私保护
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库,包含丰富的 UI 组件和常用工具函数,并且持续不断维护更新中。另外,组件库全量使用 TypeScript,支持自动按需引入和 Tree Shaking 等,能够显著提升开发效率,降低开发成本。
32 5
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
|
2天前
|
人工智能 自然语言处理 前端开发
Flame:开源AI设计图转代码模型!生成React组件,精准还原UI+动态交互效果
Flame 是一款开源的多模态 AI 模型,能够将 UI 设计图转换为高质量的现代前端代码,支持 React 等主流框架,具备动态交互、组件化开发等功能,显著提升前端开发效率。
51 1
|
3月前
「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件
本篇将带你实现一个自定义天气预报组件。用户可以通过选择不同城市来获取相应的天气信息,页面会显示当前城市的天气图标、温度及天气描述。这一功能适合用于动态展示天气信息的小型应用。
168 38
|
2月前
|
Dart 前端开发 架构师
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
153 26
|
3月前
|
人工智能 开发框架 JavaScript
LowCodeEngine:阿里开源的企业级低代码开发平台,提供预制的 UI 组件和模板,覆盖完整的研发周期
LowCodeEngine 是阿里巴巴开源的低代码开发框架,旨在通过拖拽、配置等简单操作,帮助开发者快速构建复杂的系统页面,提升开发效率和质量。
169 4
LowCodeEngine:阿里开源的企业级低代码开发平台,提供预制的 UI 组件和模板,覆盖完整的研发周期
|
4月前
|
UED
「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件
本篇将带你实现一个自定义评分星级组件,用户可以通过点击星星进行评分,并实时显示评分结果。为了让界面更具吸引力,我们还将添加一只小猫图片作为评分的背景装饰。
113 6
|
4月前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件22」鸿蒙UI组件篇12 - Canvas 组件的动态进阶应用
在鸿蒙应用中,Canvas 组件可以实现丰富的动态效果,适合用于动画和实时更新的场景。本篇将介绍如何在 Canvas 中实现动画循环、动态进度条、旋转和缩放动画,以及性能优化策略。
94 6
|
4月前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件23」鸿蒙UI组件篇13 - 自定义组件的创建与使用
自定义组件可以帮助开发者实现复用性强、逻辑清晰的界面模块。通过自定义组件,鸿蒙应用能够提高代码的可维护性,并简化复杂布局的构建。本篇将介绍如何创建自定义组件,如何向组件传递数据,以及如何在不同页面间复用这些组件。
84 5
|
3月前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。

热门文章

最新文章

  • 1
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    详解智能编码在前端研发的创新应用
  • 3
    智能编码在前端研发的创新应用
  • 4
    VSCode AI提效工具,通义灵码前端开发体验
  • 5
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
  • 8
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
  • 9
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
  • 10
    无前端经验如何快速搭建游戏站:使用 windsurf 从零到上线的详细指南