This is the third day of my participation in the August More text Challenge. For details, see: August More Text Challenge
Where the last article showed you how to encapsulate a Button component and implement different styles based on the properties, this article goes on to show you how to add font ICONS and bind custom events to the component.
1. Font ICONS
1. Download the font icon
Use the font icon in the component, need to have the font icon, can be downloaded to alibaba vector icon library. After adding your favorite icon to the library
在Project Settings, change to the following Settings to make the component complete
2. Save the font icon
Click download to the local directory
In the Asset directory, create a new font directory and store the font ICONS we downloaded. williconfont.cssPut it in the fonts folder and theniconfont.ttfandiconfont.woffPut it in the SRC folder created under fonts
3. Reference font ICONS
Change the iconfont. CSS to the following code
@font-face {
font-family: "lol-icons";
src: url('./src/iconfont.woff') format('woff'),
url('./src/iconfont.ttf') format('truetype');
}
[class*='lol-icon-'] {
font-family: "lol-icons" ! important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
Copy the code
Finally, introduce the font icon into main.js
import Vue from 'vue'
import App from './App.vue'
// Introduce the font icon
import './assets/fonts/iconfont.css'
// Import the Button component
import lolButton from './components/button.vue'
Vue.config.productionTip = false
// Register the Button component
Vue.component(lolButton.name, lolButton)
new Vue({
render: h= > h(App)
}).$mount('#app')
Copy the code
4. Use font ICONS
Now all you need is a simple label to use the font icon
<i class="lol-icon-like"></i>
Use font ICONS in the Button component
We want to use the font icon in the Button component. We can pass the font icon as a property to the Button component to use. How a Button component defines a property is described in detail in LOLstyle-UI Component Development Practices (2) — Button Component (1).
The parent component passes the icon property to the child component
<lol-button icon="lol-icon-like">Icon button</lol-button>
The child component accepts and verifies
props: {
icon: {
type: String.default: ' '
}
Copy the code
Render font icon
<template>
<button class="lol-button">
<i v-if="icon" :class="icon"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
Copy the code
Add font icon styles
i {
font-size: 14px;
}
Copy the code
According to the effect
Event binding
When we use a component, events defined directly to the component are not triggered. We need to define a click event in the component that sends a custom event to the parent component.
<template>
<button
class="lol-button"
@click="handleClick">
<i v-if="icon" :class="icon"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
Copy the code
Define the click event as, calling the parent’s click event and calling back
methods: {
handleClick (e) {
this.$emit('click', e)
}
}
Copy the code
The parent component defines its own click event when it is used. In essence, the click event in the parent component triggers the click event in the child component.
<lol-button @click="clickIt" >Click button</lol-button>
methods: {
clickIt () {
console.log('this button is clicked')}}Copy the code
Four, perfect the details
At this point a more complete Button component is complete, and you can add a few more properties according to your needs
The complete code
<template>
<button
class="lol-button"
:disabled="disabled || loading"
:autofocus="autofocus"
@click="handleClick"
:class="[{ 'is-plain': plain, 'is-round': round, 'is-circle': circle, 'is-disabled': disabled, 'is-loading': loading }]"
>
<i v-if="loading" class="lol-icon-loading"></i>
<i v-if="icon && ! loading" :class="icon"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'lolButton'.props: {
plain: {
type: Boolean.default: false
},
round: {
type: Boolean.default: false
},
circle: {
type: Boolean.default: false
},
icon: {
type: String.default: ' '
},
disabled: {
type: Boolean.default: false
},
loading: {
type: Boolean.default: false
},
autofocus: {
type: Boolean.default: false}},methods: {
handleClick (e) {
this.$emit('click', e)
}
}
}
</script>
<style lang='scss' scoped>
@mixin button-hover {
color: #f0e6d2;
border-image: linear-gradient(#f0e6d2.#DBAA41) 20 20;
}
.lol-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
border-image: linear-gradient(#cdbe91.#88652A) 20 20;
color: #cdbe91;
background: #1e2328;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
user-select: none;
outline: none;
margin: 0;
letter-spacing: 1px;
font-weight: 700;
font-size: 14px;
padding: 12px 20px;
& i {
font-size: 14px; } &+ &{margin-left: 10px;
}
&:hover{
@include button-hover;
}
&:focus{
@include button-hover;
background: linear-gradient(#1e2328.#3A3628);
}
&:active {
@include button-hover;
}
&::-moz-focus-inner {
border: 0;
}
&.is-plain {
background: rgba(30.35.40.5);
&:hover{
color: #E6B236;
border-image: linear-gradient(#f0e6d2.#DBAA41) 20 20; }} &.is-round {
border-image: none;
border: 2px #88652A solid;
border-radius: 20px;
padding: 12px 23px;
&:hover{
color: #E6B236;
border: 2px #DBAA41solid; }} &.is-circle {
border-image: none;
border: 2px #88652A solid;
border-radius: 50%;
padding: 12px;
&:hover{
color: #E6B236;
border: 2px #DBAA41solid; }} &.is-disabled, &.is-loading{&, &:hover,
&:focus{
color: #5C5B57;
background: #1E2328;
border: 2px #5C5B57 solid;
cursor: not-allowed; }}.is-loading {
cursor: wait;
}
& [class*=lol-icon-] + span {
margin-left: 5px; }}</style>
Copy the code
end
A more functional Button component is encapsulated. The next article will describe how to encapsulate a button-group component
respect by myself