前端学习案例-手动封装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>
相关文章
|
14天前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
30 0
|
3天前
|
前端开发 JavaScript 开发者
揭秘前端高手的秘密武器:深度解析递归组件与动态组件的奥妙,让你代码效率翻倍!
【10月更文挑战第23天】在Web开发中,组件化已成为主流。本文深入探讨了递归组件与动态组件的概念、应用及实现方式。递归组件通过在组件内部调用自身,适用于处理层级结构数据,如菜单和树形控件。动态组件则根据数据变化动态切换组件显示,适用于不同业务逻辑下的组件展示。通过示例,展示了这两种组件的实现方法及其在实际开发中的应用价值。
8 1
|
6天前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
14天前
|
前端开发 JavaScript
CSS样式穿透技巧:利用scoped与deep实现前端组件样式隔离与穿透
CSS样式穿透技巧:利用scoped与deep实现前端组件样式隔离与穿透
91 1
|
17天前
|
前端开发 JavaScript 开发者
Web组件:一种新的前端开发范式
【10月更文挑战第9天】Web组件:一种新的前端开发范式
18 2
|
18天前
|
JavaScript 前端开发 Java
VUE学习四:前端模块化,ES6和ES5如何实现模块化
这篇文章介绍了前端模块化的概念,以及如何在ES6和ES5中实现模块化,包括ES6模块化的基本用法、默认导出与混合导出、重命名export和import,以及ES6之前如何通过函数闭包和CommonJS规范实现模块化。
52 0
VUE学习四:前端模块化,ES6和ES5如何实现模块化
|
21天前
|
前端开发 JavaScript 小程序
前端新机遇!为什么我建议学习鸿蒙?
【10月更文挑战第4天】前端新机遇!为什么我建议学习鸿蒙?
75 0
前端新机遇!为什么我建议学习鸿蒙?
|
25天前
|
前端开发 JavaScript Go
前端开发趋势:从响应式设计到Web组件的探索
【10月更文挑战第1天】前端开发趋势:从响应式设计到Web组件的探索
29 3
|
27天前
|
存储 前端开发 Java
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
本文介绍了使用Kaptcha插件在SpringBoot项目中实现验证码的生成和验证,包括后端生成验证码、前端展示以及通过session进行验证码校验的完整前后端代码和配置过程。
31 0
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
|
2月前
|
前端开发 开发者 UED
前端只是切图仔?来学学给开发人看的UI设计
该文章针对前端开发者介绍了UI设计的基本原则与实践技巧,覆盖了布局、色彩理论、字体选择等方面的知识,并提供了设计工具和资源推荐,帮助开发者提升产品的视觉与交互体验。