import Vue from 'vue'
import App from './App.vue'
import HButton from './components/button'
import './static/iconfont.css'
Vue.config.productionTip = false
Vue.component(HButton.name, HButton)
new Vue({
render: h => h(App)
}).$mount('#app')
<h-button plain round circle icon='hButton-icon-gou' @click="showClick">默认h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='primary'>主要h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='success'>成功h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='info'>信息h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='warning'>警告h-button>
<h-button plain round circle icon='hButton-icon-gou' @click="showClick" type='danger'>危险h-button>
说明:plain就表示:plain = true;round表示:round = true;以此类推
我们通过父组件向子组件传值的方式,来处理
这里有五个常用的属性,type,plain,round,circle,disabled
<div class="hButton" :class='[
`hButton-${type}`,
{"is-plain":plain},
{"is-round":round},
{"is-circle":circle},
{"is-disabled":disabled}]'
@click="handleClick">
<i v-if="icon" :class="[icon]">i>
<span v-if="$slots.default"><slot>slot>span>
div>
.hButton-primary.is-plain{
color: #409eff;
background: #ecf5ff;
margin-left: 20px;
&:hover,
&:focus{
background: #409eff;
border-color: #409eff;
color: #fff;
}
}
.hButton-primary{
color:#fff;
background-color: #409eff;
border-color: #409eff;
margin-left: 20px;
&:hover,
&:focus{
background: #66b1ff;
background-color: #66b1ff;
color: #fff;
}
}
// 设置圆角
.hButton.is-round{
border-radius: 20px;
padding: 12px 23px;
}
// 设置圆形
.hButton.is-circle{
border-radius: 50%;
padding: 12px;
}
//设置disabled
.hButton.is-disabled{
cursor: no-drop;
}
//组件名
name: 'HButton',
// prop校验,无需校验可传入数组
props: {
type: {
type: String,
default: 'default'
},
plain: {
type: Boolean,
default: false
},
round: {
type: Boolean,
default: false
},
circle: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
icon: {
type: String,
default: ''
}
},
[class*='hButton-icon'] {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.hButton-icon-gou:before {
content: "\e610";
}
.hButton-icon-shanchu1:before {
content: "\e63c";
}
<h-button plain round circle icon='hButton-icon-gou' @click="showClick" type='danger'>危险h-button>
<i v-if="icon" :class="[icon]">i>
子向父传递的事件名一定要和要触发的事件名保持一致
@click="handleClick"
methods: {
handleClick (e) {
// 此处的事件名要和子组件的事件名一致
this.$emit('**click**', e)
}
},
<h-button plain round circle icon='hButton-icon-gou' @**click**="showClick" type='danger'>危险h-button>
methods: {
showClick () {
console.log('按钮被点击了')
}
}
1.现在有没有觉得封装一个ui组件就是利用vue的一些常见知识:如v-model,父子通信,绑定类.样式,自定义事件等等来实现,此处我们是借助Element.ui的样式来开始我们的案例,但具体我们想封装什么样的组件,我们只需要改变样式,改变事件方法,改变属性的内容等等即可。
2. 本文的主要目的是通过一个入门案例来阐述封装组件的套路和思路,接下来我们还有好多好多组件要去实现,input,dialog,calendar,等等。当我们组件库有一定数量和质量了,我们可以将我们的组件库代码发布到github上,让更多人看到和使用。
/App.vue父组件
<template>
<div id="app">
<h-button>默认</h-button>
<h-button type='primary'>主要</h-button>
<h-button type='success'>成功</h-button>
<h-button type='info'>信息</h-button>
<h-button type='warning'>警告</h-button>
<h-button type='danger'>危险</h-button>
<hr/>
<h-button plain>默认</h-button>
<h-button plain type='primary'>主要</h-button>
<h-button plain type='success'>成功</h-button>
<h-button plain type='info'>信息</h-button>
<h-button plain type='warning'>警告</h-button>
<h-button plain type='danger'>危险</h-button>
<hr/>
<h-button plain round class='hButton-icon-gou'>默认</h-button>
<h-button plain round type='primary'>主要</h-button>
<h-button plain round type='success'>成功</h-button>
<h-button plain round type='info'>信息</h-button>
<h-button plain round type='warning'>警告</h-button>
<h-button plain round type='danger'>危险</h-button>
<hr/>
<h-button plain round circle icon='hButton-icon-gou' @click="showClick">默认</h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='primary'>主要</h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='success'>成功</h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='info'>信息</h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' @click="showClick" type='warning'>警告</h-button>
<h-button plain round circle icon='hButton-icon-gou' @click="showClick" type='danger'>危险</h-button>
<hr/>
<h-button plain round circle icon='hButton-icon-gou' disabled @click="showClick"></h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' disabled @click="showClick" type='primary'></h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' disabled @click="showClick" type='success'></h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' disabled @click="showClick" type='info'></h-button>
<h-button plain round circle icon='hButton-icon-shanchu1' disabled @click="showClick" type='warning'></h-button>
<h-button plain round circle icon='hButton-icon-gou' disabled @click="showClick" type='danger'></h-button>
</div>
</template>
<script>
export default {
methods: {
showClick () {
console.log('按钮被点击了')
}
}
}
</script>
<style lang="scss">
hr{
margin: 30px auto;
}
</style>
/button.vue子组件
<template>
<div class="hButton" :class='[
`hButton-${type}`,
{"is-plain":plain},
{"is-round":round},
{"is-circle":circle},
{"is-disabled":disabled}]'
@click="handleClick">
<i v-if="icon" :class="[icon]"></i>
<span v-if="$slots.default"><slot></slot></span>
</div>
</template>
<script>
export default {
name: 'HButton',
// prop校验,无需校验可传入数组
props: {
type: {
type: String,
default: 'default'
},
plain: {
type: Boolean,
default: false
},
round: {
type: Boolean,
default: false
},
circle: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
icon: {
type: String,
default: ''
}
},
methods: {
handleClick (e) {
// 此处的事件名要和子组件的事件名一致
this.$emit('click', e)
}
},
created () {
// 获取插槽内容
console.log(this.$slots)
}
}
</script>
<style lang="scss" scoped>
// 默认样式
.hButton{
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
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;
-ms-user-select: none;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
&:hover,
&:focus{
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
}
// 各种类型样式
.hButton-primary{
color:#fff;
background-color: #409eff;
border-color: #409eff;
margin-left: 20px;
&:hover,
&:focus{
background: #66b1ff;
background-color: #66b1ff;
color: #fff;
}
}
.hButton-success{
color:#fff;
background-color: #67c23a;
border-color: #67c23a;
margin-left: 20px;
&:hover,
&:focus{
background: #85ce61;
background-color: #85ce61;
color: #fff;
}
}
.hButton-info{
color:#fff;
background-color: #909399;
border-color: #909399;
margin-left: 20px;
&:hover,
&:focus{
background: #a6a9ad;
background-color: #a6a9ad;
color: #fff;
}
}
.hButton-warning{
color:#fff;
background-color: #e6a23c;
border-color: #e6a23c;
margin-left: 20px;
&:hover,
&:focus{
background: #ebb563;
background-color: #ebb563;
color: #fff;
}
}
.hButton-danger{
color:#fff;
background-color: #f56c6c;
border-color: #f56c6c;
margin-left: 20px;
&:hover,
&:focus{
background: #f78989;
background-color: #f78989;
color: #fff;
}
}
// 各种类型朴素样式
.hButton.is-plain{
&:hover,
&:focus{
background: #fff;
border-color: #489eff;
color: #409eff;
}
}
.hButton-primary.is-plain{
color: #409eff;
background: #ecf5ff;
margin-left: 20px;
&:hover,
&:focus{
background: #409eff;
border-color: #409eff;
color: #fff;
}
}
.hButton-success.is-plain{
color: #67c23a;
background: #c2e7b0;
margin-left: 20px;
&:hover,
&:focus{
background: #67c23a;
border-color: #67c23a;
color: #fff;
}
}
.hButton-info.is-plain{
color: #909399;
background: #d3d4d6;
margin-left: 20px;
&:hover,
&:focus{
background: #909399;
border-color: #909399;
color: #fff;
}
}
.hButton-warning.is-plain{
color: #e6a23c;
background: #f5dab1;
margin-left: 20px;
&:hover,
&:focus{
background: #e6a23c;
border-color: #e6a23c;
color: #fff;
}
}
.hButton-danger.is-plain{
color: #f56c6c;
background: #fbc4c4;
margin-left: 20px;
&:hover,
&:focus{
background: #f56c6c;
border-color: #f56c6c;
color: #fff;
}
}
// 设置圆角
.hButton.is-round{
border-radius: 20px;
padding: 12px 23px;
}
// 设置圆形
.hButton.is-circle{
border-radius: 50%;
padding: 12px;
}
//设置disabled
.hButton.is-disabled{
cursor: no-drop;
}
//所有图标后的span左边距
[class*='hButton-icon']+span{
margin-left: 5px;
}
</style>
/main.js文件入口
import Vue from 'vue'
import App from './App.vue'
import HButton from './components/button'
import './static/iconfont.css'
Vue.config.productionTip = false
Vue.component(HButton.name, HButton)
new Vue({
render: h => h(App)
}).$mount('#app')