Part 6: Implementing a set of ui component library (loading) components of vue on pc side from scratch

Episode 6: Implementing from scratch (loading components)

Location of this episode:
loading component I believe that as long as there are projects interacting with the back end, it is needed. Although the component is simple, its role is very important:

  1. Let the user have a good experience, that is, to give the user a signal,'I'm doing it, wait'.
  2. Obscure the user's operation, that is, during this period (possibly) the user is not allowed to trigger other events.
  3. Don't let users see the white screen, the experience of seeing the white screen is poor to explosion.
  4. All kinds of cool effects are also a means of eye-catching.

1: loading demand analysis

  1. When appearing, the user's operation should be blocked.
  2. Dependent on dom, you can control its appearance and hiding through js, such as configuring axios.
  3. Fill the parent, not the body, because it's the pc end, so it's not a small black block.

Discussion of the progress bar above the screen
I used the progress bar in last year's project. The experience was too bad to be conspicuous. I couldn't click on the screen to make people confused. So I don't need it this time.

Discussions on Skeleton Screen
The next chapter will do (simple skeleton screen).
Many technical directions are to show the shadow of the dom structure perfectly. In fact, I don't feel the need to restore the dom that has not been loaded by 1:1. It's just a general look in the transition stage. More energy and ability are put into the business. According to my observation of a lot of app s, 100% of the restored DOMS are really not much. And I asked many friends if they noticed the deviation between the skeleton screen and the real dom structure, all of them said they didn't notice it, so the skeleton screen components only do the most basic functions.

II: Construction of Infrastructure
Template

<template>
// Old rules:
  <div class="cc-loading">
// Black shade
    <div class="cc-loading__curtain"/>
    // icon and content display area
    <section class="cc-loading__icon">
    // icon component
      <ccIcon :name='iconName'
              :color='iconColor' />
    // Displayed prompt text
      <span>{{title}}</span>
    </section>
</template>

js

props: {
    title: {
      type: String,
      default: "Loading . . ."
    },
    iconName: {  // The way the icon is loaded must be user-defined
      type: String,
      default: "cc-load1" // The default is common Chrysanthemum
    },
    iconColor: { // The color of the icon is also determined by the user himself, in case of special needs.
      type: String,
      default: "#3F8BDB"
    }
  }

The css part is encapsulated for center and location.

@import './common/var.scss';
@import './common/extend.scss';
@import './common/mixin.scss';

@include b(loading) {
    @include position();
    &__curtain{
        @include position();
    }
    &__icon{
        position: absolute;
        color: $--color-nomal;
        z-index: 10;
        @include flexCenter;
        @include position();
        :nth-child(1){ // Separation between text and Icon
            margin-bottom:6px;
        }
    }
}

src/style/common/mixin.scss

@mixin position($position: absolute) {
  margin: auto;
  position: $position;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

@mixin flexCenter {
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
}

Use Display

// When you need to display, let the dom display, because the default is to locate the browser.
<cc-loading v-if='show' />

Third: Father-level positioning, not global loading
In fact, it is very simple, that is, the difference of attributes, fixed location can be replaced, can be replaced by a wave of adsorption attributes.
Let me add a lot of friendly attributes.

<template>
  <div class="cc-loading"
       :style="{
           'zIndex':boxZIndex,  // Hierarchy
           'position': position // Location mode
        }">
    <div class="cc-loading__curtain"
         :style="{
             'opacity':opacity, // The transparency of this layer will also be friendly for users to fill in.
             'background-color':curtainColor  // The color is also the user's choice.
            }" />
    <section class="cc-loading__icon"
          :style="{
              'fontSize':iconSize+'px'   // Icon size
              }">
      <ccIcon :name='iconName'
              :color='iconColor' />
      <span :style="{
          'fontSize':textFontSize+'px', // The size of the text
          'color':textColor  // The Color of Text
          }">{{title}}</span>
    </section>

  </div>
</template>

js, the default values are the common values of this set of projects;

 props: {
    position: {
      type: String,
      default: "fixed"
    },
    title: {
      type: String,
      default: "Loading . . ."
    },
    textColor: {
      type: String,
      default: "#3F8BDB"
    },
    opacity: {
      type: Number,
      default: 0.8
    },
    iconName: {
      type: String,
      default: "cc-load1"
    },
    iconColor: {
      type: String,
      default: "#3F8BDB"
    },
    curtainColor: {
      type: String,
      default: "black"
    },
    boxZIndex: {
      type: Number,
      default: 100
    },
    textFontSize: {
      type: Number,
      default: 17
    },
    iconSize: {
      type: Number,
      default: 25
    }
  },

Effect Show

4: Adding Events and js Programming Calls

In fact, even if it is a masked state, it also needs to give a click event, such as users click a lot of times, can give users a pop-up'right now, and can't stand it any more', users can do it themselves through the natural modifier, but that's too inexpensive.

<div class="cc-loading"
       @click.stop="onClickLoading">
 onClickLoading() {
      this.$emit("click");
    }

Don't forget to add the stop modifier, or click through will be a bad thing.

More often than not, we need to control the loading state from js mode
vue-cc-ui/src/components/loading/main/loading.js

// Introducing Written Components
import Loading from './loading.vue';

Loading.install = function(Vue) {
// Register for use
  Vue.component(Loading.name, Loading);
// Hang a wave on the prototype
  Vue.prototype.$ccShowLoading = function(options) {
// Extended is instantiating this component
    let Constructor = Vue.extend(Loading);
    let node = new Constructor({
      propsData: options // All configurations are passed in as well.
    });
    // Execute his hook
    node.vm = node.$mount();
    // Insert body, because there is no need to insert a fixed parent, users can also pass it on themselves.
    document.body.appendChild(node.$el);
  };
// If it appears, it will disappear.
  Vue.prototype.$ccHiddenLoading = function() {
   // Find the class on the body for this element and kill it.
    document.body.childNodes.forEach(item => {
      if (item.className === 'cc-loading') {
        document.body.removeChild(item);
      }
    });
  };
};

export default Loading;

Next Chapter: Simple Skeleton Screen
Welcome to progress together!

github: Link Description
Personal website: Link Description

Keywords: Javascript Vue axios Programming github

Added by MattAdamson on Tue, 30 Jul 2019 16:22:00 +0300