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