第六集: 從零開始實現一套pc端vue的ui組件庫( loading )組件

第六集: 從零開始實現(loading組件 )

本集定位 :
loading組件我相信只要與後端存在交互的項目都是須要它的, 組件雖然簡單, 但他的做用十分重要:css

  1. 讓用戶有一個良好的體驗, 也就是反饋給用戶一個信號, '我正在作, 再等等...'.
  2. 遮擋住用戶的操做, 也就是此期間(有可能)不讓用戶再去觸發其餘事件.
  3. 不讓用戶看到白屏, 看到白屏的體驗差到爆炸啊.
  4. 各類炫酷的效果, 也是吸睛的一種手段.

一: loading需求分析 vue

  1. 出現之時, 要遮擋用戶的操做.
  2. 不依賴dom, 要經過js就能控制它的出現與隱藏, 好比配置axios.
  3. 充滿父級, 而不是充滿body, 由於是pc端, 因此不是小黑塊的形式.

屏幕上方進度條的討論
我去年的工程裏面用的進度條, 體驗太差了, 不夠顯眼, 屏幕上不能點擊讓人懵圈, 因此本次不用.node

骨架屏的討論
    下一章會作(簡易版骨架屏).
不少技術方向, 是爲了完美展現dom結構的陰影, 1:1的還原還未加載出的dom的樣子, 其實我感受不用這樣把.... 只是個過渡階段有個大體的樣子就能夠了, 更多的精力與能力放在業務上, 據我觀察了不少app, 真的100%還原的真的很少, 並且我問過不少朋友是否注意到骨架屏與真實的dom結構存在誤差, 全都說沒注意到, 因此骨架屏這方面本套組件只作最基本的功能.ios

二: 基礎結構的搭建
模板git

<template>
// 老規矩:
  <div class="cc-loading">
// 黑色的遮罩層
    <div class="cc-loading__curtain"/>
    // icon與內容顯示區
    <section class="cc-loading__icon">
    // icon組件
      <ccIcon :name='iconName'
              :color='iconColor' />
    // 顯示的提示文字
      <span>{{title}}</span>
    </section>
</template>

jsgithub

props: {
    title: {
      type: String,
      default: "加載中 . . ."
    },
    iconName: {  // 加載圖標的樣子確定是用戶自定義的
      type: String,
      default: "cc-load1" // 默認就是普通的菊花
    },
    iconColor: { // 圖標的顏色也是用戶本身定的, 萬一有特殊需求
      type: String,
      default: "#3F8BDB"
    }
  }

css部分, 針對居中與定位都有封裝.編程

@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){ // 文字與圖標分的開一些
            margin-bottom:6px;
        }
    }
}

src/style/common/mixin.scssaxios

@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;
}

使用顯示後端

// 須要顯示的時候, 讓這個dom顯示便可, 由於默認是對瀏覽器定位的.
<cc-loading v-if='show' />

基礎加載樣式

三: 針對父級定位, 而不是全局的loading
其實很簡單, 也就是屬性的差異, 把fixed定位換掉便可, 均可以換上吸附屬性浪一浪
讓我來加不少友好的屬性瀏覽器

<template>
  <div class="cc-loading"
       :style="{
           'zIndex':boxZIndex,  // 層級
           'position': position // 定位方式
        }">
    <div class="cc-loading__curtain"
         :style="{
             'opacity':opacity, // 這個層的透明度也會友好的讓用戶填寫
             'background-color':curtainColor  // 顏色也是用戶選
            }" />
    <section class="cc-loading__icon"
          :style="{
              'fontSize':iconSize+'px'   // 圖標的大小
              }">
      <ccIcon :name='iconName'
              :color='iconColor' />
      <span :style="{
          'fontSize':textFontSize+'px', // 文字的大小
          'color':textColor  // 文字的顏色
          }">{{title}}</span>
    </section>

  </div>
</template>

js, 這裏面的默認值都是本套工程的共用值;

props: {
    position: {
      type: String,
      default: "fixed"
    },
    title: {
      type: String,
      default: "加載中 . . ."
    },
    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
    }
  },

效果展現
圖片描述
圖片描述

四: 添加事件與js編程式調用

其實就算是蒙層狀態, 也要給個點擊事件, 好比用戶點了不少下, 能夠給用戶彈出一個'立刻好,再點受不了了...', 用戶能夠本身經過native修飾符去作, 可是那樣太不工程化了.

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

別忘了加stop修飾符, 否則點擊穿透可就壞事了.

咱們更多時候是要從js的方式控制加載狀態的
vue-cc-ui/src/components/loading/main/loading.js

// 引入寫好的組件
import Loading from './loading.vue';

Loading.install = function(Vue) {
// 註冊一下才能使用
  Vue.component(Loading.name, Loading);
// 在原型上掛在一波
  Vue.prototype.$ccShowLoading = function(options) {
// extend也就是實例化這個組件
    let Constructor = Vue.extend(Loading);
    let node = new Constructor({
      propsData: options // 全部的配置也都如數傳進去
    });
    // 執行到他的鉤子
    node.vm = node.$mount();
    // 插入body, 由於這個就不必插入固定的父級了, 用戶本身傳也能夠
    document.body.appendChild(node.$el);
  };
// 有出現就要有消失
  Vue.prototype.$ccHiddenLoading = function() {
   // 從body上面找到class爲這個的元素就幹掉.
    document.body.childNodes.forEach(item => {
      if (item.className === 'cc-loading') {
        document.body.removeChild(item);
      }
    });
  };
};

export default Loading;

下一章: 簡易版骨架屏
歡迎你們一塊兒進步!

github: 連接描述
我的網站: 連接描述

相關文章
相關標籤/搜索