模拟Element的自定义Button组件

模拟Element的自定义Button组件一 使用 vue 脚手架初始化一个项目 使用 vue created Tianm 创建一个名为 Tianm 的项目 按照自己的习惯设置脚手架风格 这里不多做介绍 脚手架搭建完毕后 将 App vue 文件下的自带内容清理一下 为后续开发做准备 二 如何封装 注册和使用一个组件 在 componet 下创建一个 button

大家好,我是讯享网,很高兴认识大家。

按照自己的习惯设置脚手架风格,这里不多做介绍。

脚手架搭建完毕后,将App.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> <one-button></one-button> </div> </template> 

组件最简单的封装,注册和使用方法就是这样一个流程。

组件通讯
组件插槽
props校验
参数支持:

参数名 参数描述 参数类型 默认值
type 按钮类型(primary/success/warning/danger/info) string default
plain 是否是朴素按钮 boolean false
round 是否是圆角按钮 boolean false
circle 是否是圆形按钮 boolean false
disabled 是否禁用按钮 boolean false
icon 图标类名 string 无
事件支持:

事件名 事件描述
click 点击事件
使用插槽:

简单来说,凡是希望组件中内容可以灵活设置的地方,都需要用到slot插槽来自定义内容。

使用slot来定义按钮上的文本内容:

讯享网<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> 

button组件基础样式:

讯享网<style lang="scss"> .one-button{ 
    display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: #ffffff; border: 1px solid #dcdfe6; color: #; -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> 

第一步:父组件组件传递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> 

第二步:子组件接收负组件传递的数据

讯享网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进行校验,如果传递了非String类型的值(这里我传递了123),将会报错。

failed for prop "type". Expected String with value "123", got Number with value 123. 

第三步:通过绑定类名的方法动态控制样式

讯享网<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: #; border-color: #; &: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; } } 

第一步:父组件组件传递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: #; background: #d3d4d6; &:hover, &:focus{ 
    background: #; border-color: #; 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: { 
    type: Boolean, default: false } round样式: .one-button.is-round{ 
    border-radius: 20px; padding: 12px 23px; } 3.4button组件的circle属性 circle同样是上面的方法,样式为: .one-button.is-circle{ 
    border-radius: 50%; padding: 12px; } 

下载完成后,在asset目录下新建一个fonts目录,存放我们下载到的字体图标。

做完准备工作后,我们就可以开始把字体图标运用到项目中了。

第一步:在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时隐藏标签,在slot插槽没有传入值时,不显示标签

<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; } 

组件中的定义点击事件:

<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('获取信息!!')//获取信息!! } } 
讯享网<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; } 

附组件代码:

<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: #; -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: #; border-color: #; &: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: #; background: #d3d4d6; &:hover, &:focus{ 
    background: #; border-color: #; 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> 
小讯
上一篇 2025-03-13 20:01
下一篇 2025-01-18 09:21

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/41742.html