Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基于Vue实现加载进度条插件 #25

Open
ChenJiaH opened this issue Aug 2, 2019 · 0 comments
Open

基于Vue实现加载进度条插件 #25

ChenJiaH opened this issue Aug 2, 2019 · 0 comments
Labels

Comments

@ChenJiaH
Copy link
Owner

ChenJiaH commented Aug 2, 2019

首发于微信公众号《前端成长记》,写于 2018.02.26

概述

随着越来越多的网站采用顶部加载进度条来表示加载进度及状态,效果如下:

image

查看在线示例

使用

配置文档

可以单独在请求中使用,也可以使用在路由切换过程中。比如结合 vue-router 使用:

import loadingBar from  '../src/components/loading-bar/loading-bar'
router.beforeEach((to, from, next) => {
   if(to.path === "/" && to.name === "Home") {
      router.replace({path: '/summary'});
      next();
   } else {
      loadingBar.start();
      next();
   }
});
router.afterEach((to, from) => {
   loadingBar.finish();
});

源码

Github

实现方式

基于 Vue 的调用方式一般有两种:** 组件方式 ** 和 ** 插件方式 **。

推荐使用 插件方式 调用,当然如果只有一处使用的话,也可以使用组件方式。

  1. 首先编写一个单文件组件

该文件中含有进度条的样式结构以及一些动态入参,示例:

<template>
    <transition name="loading-fade">
        <div class="jrv-loading-bar" :style="barStyle" v-show="show">
            <div class="jrv-loading-bar-inner" :style="{'width': innerWidth, 'background-color': [status == 'success' && successBg, status == 'fail' && failBg,],}"
                 :class="{'jrv-loading-bar-inner_success': status == 'success', 'jrv-loading-bar-inner_fail': status == 'fail'}"></div>
        </div>
    </transition>
</template>
<script>
   export default {
      name: "jrvLoadingBar",
      data() {
         return {
            percent: 0,
            status: 'success',
            show: false,
            barBg: 'transparent',
            successBg: null,
            failBg: null,
         }
      },
      computed: {
         barStyle() {
            return {
               backgroundColor: `${this.barBg}`,
            }
         },
         innerWidth() {
            return this.percent + '%';
         },
      },
   }
</script>
<style type="text/scss" lang="scss">
    @import '../../../styles/components/_loading-bar.scss';
</style>

在上述代码中,可以发现入参主要有: percent(进度) status(状态) show(显示与否) barBg(背景色) successBg(成功背景色) failBg(失败背景色),所以使用起来,只需要修改这几个主要动态参数即可。

  1. 接下来是插件方式的调用

创建一个 loading-bar.js 文件,代码如下:

/**
 * @Author: Created By McChen
 * @Date: 2017/10/27
 * @Mail: [email protected]
 * @Version: V1.0.0
 */
 
import Vue from 'vue'
 
// 引入上面定义的单文件组件
import loadingBar from './src/loading-bar'
 
// 实例对象
let instance;
// 定时器
let timer;
 
let LoadingBar = {
   create () {
      if(!instance) {
         // 组件构造器
         const LoadingBarConstructor = Vue.extend(loadingBar);
         instance = new LoadingBarConstructor({});
         // 挂载实例
         instance.$mount();
         document.body.appendChild(instance.$el);
      }
   },
   update (options) {
      // 修改动态入参值
      for(let key in options) {
         instance[key] = options[key];
      }
   },
   hide () {
      let timer1 = setTimeout(() => {
         this.update({
            show: false
         });
         clearTimeout(timer1);
 
         let timer2 = setTimeout(() => {
            this.update({
               percent: 0
            });
            clearTimeout(timer2)
         }, 200);
      }, 800);
   },
   destroy () {
      document.body.removeChild(document.getElementsByClassName('jrv-loading-bar')[0]);
   },
   clearTimer () {
      if(timer) {
         clearInterval(timer);
         timer = null;
      }
   }
};
// 默认先创建一个
LoadingBar.create();
 
export default {
   config (obj) {
      LoadingBar.update({
         barBg: obj.barBg,
         successBg: obj.successBg,
         failBg: obj.failBg,
      })
   },
   start () {
      LoadingBar.create();
 
      if(timer) {
         return false;
      } else {
         let percent = 0;
 
         LoadingBar.update({
            percent: percent,
            status: 'success',
            show: true
         });
 
         timer = setInterval(() => {
            percent += Math.floor(Math.random () * 3 + 5);
            if (percent > 90) {
               clearInterval(timer);
               timer = null;
            }
            LoadingBar.update({
               percent: percent,
               status: 'success',
               show: true
            });
         }, 200);
      }
   },
   update (percent) {
      LoadingBar.clearTimer();
      LoadingBar.update({
         percent: percent,
         status: 'success',
         show: true
      });
   },
   finish () {
      if(timer) {
         LoadingBar.clearTimer();
         LoadingBar.update({
            percent: 100,
            status: 'success',
         });
         LoadingBar.hide();
      } else {
         LoadingBar.hide();
      }
   },
   error () {
      LoadingBar.clearTimer();
      LoadingBar.update({
         percent: 100,
         status: 'fail',
      });
      LoadingBar.hide();
   },
   destroy () {
      LoadingBar.clearTimer();
      instance = null;
      LoadingBar.destroy();
   },
}

结尾

其实不单单是 props 属性,你可以使用继承过来的 vue 对象的任意东西,怎么使用全凭各位的创造力啦~

(完)


本文为原创文章,可能会更新知识点及修正错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验
如果能给您带去些许帮助,欢迎 ⭐️star 或 ✏️ fork
(转载请注明出处:https://chenjiahao.xyz)

@ChenJiaH ChenJiaH added the vue.js label Aug 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant