谁经历的苦难多,谁懂得的东西也就多。
前言
在做头像上传功能时,为了防止用户多次点击,通常会在上传时添加一个遮罩,提示用户:图片正在上传中,上传完毕后,关闭这个遮罩层,本来想找个UI框架引入进来,使用框架提供的弹层,找了很多没找到满意的,干脆自己做一个吧😂。接下来就跟大家分享下如何制作一个插件,先跟大家展示下最终实现的效果:
实现思路
涉及到的知识点:Vue 构造器、实例挂载
- 编写加载层业务代码,实现全局加载层的相关效果
- 在插件包的index.js中进行相关封装
- 定义插件对象,实现install方法
- 使用Vue.extend构造器,将加载层业务代码作为构造器的参数创建子类
- 实例化创建的构造器,挂载到HTMLElement实例上
- 将构造器中的dom元素插入到body中
- 添加实例方法,挂载至Vue原型
- 实现显示和隐藏方法
- 插件开发完毕
实现过程
- 搭建插件开发环境
- 如图所示:在一个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
登录成功
发布成功
- 在npm官网搜索刚才发布的包
- 包地址:vue-fullscreenloading
使用插件
- 终端执行: yarn add @likaia/vue-fullscreenloading
- 在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); }
写在最后
- 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊