This is the fourth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

Base component: Button

preface

From here, the series moves into component development, starting with the base components and building a project component library step by step, as described in the previous section on component classification

At the end of the series, I show you how to pull components out of a project and package them into a separate component library.

Among the basic components, the most commonly used and least visible are Button and Mask, which are often used as green leaves.

And since this series is written from 0 to 1, so nature begins from simple first, red flower is colourful not colourful, see green leaf beautiful not beautiful.

So why start with Button instead of the simpler looking Mask?

Nature has a reason, right?

When the Mask article is updated tomorrow, we will know the thinking point of the Mask component.

Start with the folder

The step of how to package component libraries is left at the end, as the end of 1. The development context for the entire article is based on the project, but preparations need to be made for final packaging.

The file structure is as follows,

Root/SRC | | - components | | - Button | | - Button. Vue file / / subject, because use the setup - method of script writing, no name attribute, file name, carefully named | - index. Js / / exportCopy the code

Layout code

Because the style of things more freewill, you can play freely, so in this article, will pay more attention to the function of Vue3 syntax and component function cheese point sharing.

As mentioned earlier, the structure part will be done using PUG, but the essence is not very different from HTML, which will be explained in the features section.

<template lang="pug"> <! -- you must add this sentence to pug syntax, --> block content button(class="yx-btn" :class="className" :disbaled="isDisabled") span(v-if="loading") Class ="yx-load"; class="yx-load"; class="yx-btn-content" :style="style"; Please note that v-if="icon! == "" :class="icon") span(v-if="$slots. Default ")Copy the code

The structure part above is my personal writing method. In practice, I can complete this part according to my personal needs and ideas.

A few points to note:

1, we generally use solid, linear, rounded corners, circle, ICONS and other possibilities, through attribute control

2. Theme ICONS, such as success, Warning, Danger and other common types

3, size, of course, this is the category of style, not much consideration

4, whether to disable not to say, also simple

The logical part

The logical part of the button is not much. It mainly determines whether to display the style of the specified type and whether to display the icon.


<script setup>
import { computed, defineProps, toRefs } from "@vue/runtime-core";

const props = defineProps({ / / define the props
  type: { // Control button theme
    type: String.default: 'default'.validator: value= > [
      'success'.'primary'.'warning'.'info'.'danger'.'default'.'text'
    ].includes(value)
  },
  size: {  // Control button size, default MD middle medium
    type: String.default: 'md'.validator: value= > ['lg'.'sm'.'md'].includes(value)
  },
  icon: String.// Whether to display the icon
  plain: Boolean./ / linear
  round: Boolean./ / the rounded
  clrcle: Boolean./ / round
  block: Boolean.// Display: block; Monopolize the entire line
  disabled: Boolean./ / disable
  loading: Boolean // loading
})
// Add the corresponding class name according to the user's type value
const useClass = ({props, loading}) = > { 
  return computed( () = > {
    return [
      props.type && `yx-btn-${props.type}`, props.size ! = =' ' || props.size ? `yx-btn-${props.size}` : ' ',
      {
        'is-plain': props.plain,
        'is-round': props.round,
        'is-circle': props.circle,
        'is-block': props.block,
        disabled: props.disabled
      },
      loading.value && 'yx-btn-loading']})}const isDisabled = computed(() = > { props.loading || props.disabled })
const { loading, icon} = toRefs(props);
const className = useClass({
  props,
  loading,
  icon
})

// For loading, optional as required.
const style = computed(() = > {
  return props.loading ? {opacity: '0'.transform: 'scale (2.2)'}, {}; }) </script>Copy the code

That’s the logical part. The simplest button can have no logic at all, but then you can use the button label directly.

The button component is basically the normal part and some style customization. It doesn’t go too deep into some of Vue3’s features.

But since we’re starting at zero, we’re definitely starting at easy and getting deeper.

When you develop your own components, the logic of the component itself is basically a very subjective part. Later, you will omit this part for some components with no logical requirements, and only share some characteristic functions.

Export components

import ele from './button.vue'

// ele.name: component name
// Since setup-script does not have a name attribute, the default name is a file name, but you can customize it.
ele.install = function(app){ // The app parameter here automatically calls install when the component is introduced, passing in the Vue instance as the parameter
  app.component(ele.name, ele);
  app.component('yxButton', ele); // Customize the component name
}
export default ele;
Copy the code

Write here, you can in the main. Js or need interface through the import yxButton from ‘@ / SRC/components/button/index’ import for use.

It’s a bit of a hassle, it’s just a newborn component at the moment, but at the end of the day we’ll wrap up the component library and introduce it on demand just like any other open source component library.

Write in the last

The component in this article is the simplest and simplest of buttons, with the main part being to export the component and mount it on the Vue instance at the end. Overall, there is little difference from Vue2.