Vue实现一个全屏加载插件并发布至npm仓库

简介: Vue实现一个全屏加载插件并发布至npm仓库

谁经历的苦难多,谁懂得的东西也就多。


前言


在做头像上传功能时,为了防止用户多次点击,通常会在上传时添加一个遮罩,提示用户:图片正在上传中,上传完毕后,关闭这个遮罩层,本来想找个UI框架引入进来,使用框架提供的弹层,找了很多没找到满意的,干脆自己做一个吧😂。接下来就跟大家分享下如何制作一个插件,先跟大家展示下最终实现的效果:


640.gif


实现思路


涉及到的知识点:Vue 构造器、实例挂载


  • 编写加载层业务代码,实现全局加载层的相关效果
  • 在插件包的index.js中进行相关封装
  • 定义插件对象,实现install方法
  • 使用Vue.extend构造器,将加载层业务代码作为构造器的参数创建子类
  • 实例化创建的构造器,挂载到HTMLElement实例上
  • 将构造器中的dom元素插入到body中
  • 添加实例方法,挂载至Vue原型
  • 实现显示和隐藏方法
  • 插件开发完毕


实现过程


  • 搭建插件开发环境


640.png


  • 如图所示:在一个Vue项目的src目录下创建lib文件夹,用于存放各种插件
  • 在lib文件夹下创建我们的插件文件夹(FullScreenLoading)
  • 在插件文件夹下分别创建lib文件夹和index.js文件
  • 插件文件夹下的lib文件夹用于存放插件需要用到的资源文件
  • index.js文件用于实现这个插件的所有逻辑


  • 插件业务代码(FullScreenLoading.vue)


<template>
    <div id="loadingPanel" v-if="show">
        <div class="container-panel">
            <div class="arc"></div>
            <h1><span>{{tips}}</span></h1>
        </div>
    </div>
</template>
<script>
    export default {
        name: "FullScreenLoading",
        data(){
            return{
                tips:"加载中",
                show:false
            }
        }
    }
</script>
<style src="./css/FullScreenLoading.css">
</style>


  • 插件样式代码(FullScreenLoading.css)


body {
    font-family: 'Inconsolata', monospace;
    overflow: hidden;
}
/*全屏遮罩层*/
#loadingPanel{
    width: 100%;
    height: 100%;
    background: rgba(11,11,20,.6);
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9999;
    display: flex;
    justify-content: center;
    align-items: center;
}
#loadingPanel.container-panel{
    width: 200px;
    height: 200px;
    display: flex;
    justify-content: center;
    align-items: center;
}
#loadingPanel.container-panel.arc {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    border-top: 2px solid #ffea29;
    border-left: 1px solid transparent;
    border-right: 1px solid transparent;
    animation: ring 2s infinite linear;
}
#loadingPanel.container-panel.arc::before {
    position: absolute;
    margin: auto;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 70px;
    height: 70px;
    border-radius: 50%;
    border-top: 2px solid #8d29ff;
    border-left: 1px solid transparent;
    border-right: 1px solid transparent;
    animation: ring 4s infinite linear reverse;
    content: "";
}
#loadingPanel.container-panel.arc::after {
    position: absolute;
    margin: auto;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 0;
    height: 0;
    border-radius: 50%;
    border-top: initial;
    border-left: initial;
    border-right: initial;
    animation: solidCircle 1s infinite;
    content: "";
    background: snow;
}
#loadingPanel.container-panelh1 {
    position: absolute;
    height: 40px;
    margin: auto;
    top: 200px;
    left: 0;
    right: 0;
    bottom: 0;
    text-transform: uppercase;
    text-align: center;
    letter-spacing: 0.1em;
    font-size: 14px;
    font-weight: bold;
    color: white;
}
/*动画定义*/
@keyframes ring {
    100% {
        transform: rotate(360deg);
    }
}
@keyframes solidCircle {
    0% {
        width: 0;
        height: 0;
    }
    75% {
        width: 40px;
        height: 40px;
    }
    100% {
        width: 0;
        height: 0;
    }
}


  • 插件逻辑文件(index.js)


// 引入对应的组件
import loading from"./lib/FullScreenLoading";
// 定义对象:开发插件对象
const LoadPlugin = {
    // 插件包含install方法
    install(Vue,options){
        // 使用Vue.extend构造器,创建一个子类,参数为引入的FullScreenLoading组件
        const loadingSubclass = Vue.extend(loading);
        // 实例化loadingSubclass,挂载到HTMLElement实例上
        const Profile = new loadingSubclass({
            el: document.createElement('div')
        });
        // 插入到body中,FullScreenLoading.vue中的template模板内容将会替换挂载的元素,Profile.el中到内容最终为模版到内容
        document.body.appendChild(Profile.$el);
        // 判断是否有传参数:替换组件内的默认显示数据
        if(options){
            if(options.tips){
                Profile.tips = options.tips;
            }
        }
        // 添加实例方法,挂载至Vue原型
        Vue.prototype.$fullScreenLoading = {
            // 定义显示隐藏的方法
            show(tips) {
                Profile.show = true;
                if (tips) {
                    // 替换组件的默认数据
                    Profile.tips = tips;
                }
            },
            hide() {
                Profile.show = false;
            }
        };
    }
};
// 导出对象
exportdefault LoadPlugin;


至此,插件开发完毕。本文开头实现的效果,项目地址:chat-system


插件发布


  • 在终端进入到FullScreenLoading文件夹内
  • 创建README.md编写插件描述以及使用方法
  • 终端执行npm init命令,生成package.json文件


npm init
 # 应用包名,要先去https://www.npmjs.com/官网查一下是否与你的包重复
 package name: (@likaia/vue-fullscreenloading)
 # 版本号
 version: (1.0.0)
 # 包描述
 description: 全屏加载层插件,提升用户体验,防止用户误操作。
 # 入口文件
 entry point: (index.js)
 # 测试命令,直接回车即可
 testcommand:
 # 项目git仓库地址
 git repository: https://github.com/likaia/chat-system.git
 # 关键词:用户在npm官网搜索包时所用的关键词
 keywords: vue-loading FullScreenLoading
 # 作者
 author: likaia
 # 开源协议,直接回车即可
 license: (ISC)


  • 发布到npm仓库


# 登录,没有账号的需要先去官网注册:https://www.npmjs.com/
npm login
# 发布至npm
npm publish --access=public


登录成功

640.png

发布成功

640.png


  • 在npm官网搜索刚才发布的包


640.png


  • 包地址:vue-fullscreenloading


使用插件


  • 终端执行: yarn add @likaia/vue-fullscreenloading


640.png


  • 在main.js中进行引用


import FullScreenLoading from'@likaia/vue-fullscreenloading'
Vue.use(FullScreenLoading);


  • 在业务中使用


uploadAvatar:function (e) {
  console.log("上传点击了");
  // 显示全局加载层
  this.$fullScreenLoading.show("上传中");
  let file = e.target.files[0];
  // 构造form对象
  let formData = new FormData();
  // 后台取值字段 | blob文件数据 | 文件名称
  formData.append("file",file,file.name);
  // 调用上传api
  this.$api.fileManageAPI.baseFileUpload(formData).then((res)=>{
    console.log(res);
    const fileName = `${base.lkBaseURL}/uploads/${res.fileName}`;
    // 更改默认头像状态
    this.isDefaultAvatar = false;
    // 头像赋值
    this.avatarSrc = fileName;
    // 隐藏全局加载层
    this.$fullScreenLoading.hide();
  });
  console.log(e);
}


写在最后


  • 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊
相关文章
|
20天前
|
缓存 JavaScript 前端开发
vue如何优化首页加载速度
vue如何优化首页加载速度
25 7
|
1月前
|
缓存 JavaScript 前端开发
vue如何优化首页加载速度?
vue如何优化首页加载速度?
21 0
|
2月前
|
开发框架 JavaScript 前端开发
vue首次加载白屏问题
vue首次加载白屏问题
38 0
|
3月前
|
前端开发 JavaScript
Vue中使用纯CSS实现全屏网格加渐变色背景布局
Vue中使用纯CSS实现全屏网格加渐变色背景布局
76 0
|
3月前
|
缓存 JavaScript 前端开发
Vue状态管理:请解释Vue中的异步组件加载是如何工作的?
Vue状态管理:请解释Vue中的异步组件加载是如何工作的?
23 0
|
2月前
|
JavaScript
vue 实现表格循环滚动 vue-seamless-scroll插件的安装与使用
vue 实现表格循环滚动 vue-seamless-scroll插件的安装与使用
|
3月前
|
前端开发 API 开发者
Vue3如何优雅的加载大量图片?
Vue3如何优雅的加载大量图片?
|
1月前
|
JavaScript
vue中如何实现全全全屏和退出全屏?
vue中如何实现全全全屏和退出全屏?
20 0
|
1月前
|
JavaScript API
Vue3通信方式之defineProps、defineEmits、useAttrs、插件mitt和v-model
Vue3通信方式之defineProps、defineEmits、useAttrs、插件mitt和v-model
28 0
|
1月前
|
JavaScript 网络安全 数据安全/隐私保护
【问题:创建Vue项目】npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR!
【问题:创建Vue项目】npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR!

推荐镜像

更多