之前写了《发布一个npm包》,接着尝试写一个简单的基于vue的插件并发布到npm。
插件功能:
1.全屏loading插件
2.调用show(tips)方法启用 - tips为loading时的文案
3.调用hide()方法关闭
这次的插件使用了vue-cli 3.x。
一、vue-cli 3.x 初始化项目
首先确保自己电脑上安装了vue-cli 3.x,如果之前安装了低于3.0版本的可以手动卸载,重新安装3.0以上
1.卸载低版本的 vue-cli
npm uninstall vue-cli -g
2.安装新版本 @vue/cli
npm install -g @vue/cli
3.创建项目
vue create project-name // project-name自定义项目名称
4.启动项目
npm run serve
二、新建插件目录
我在src下新建lib文件夹来存放我的插件
lib目录下新建 .vue文件写业务代码
lib目录下新建 .js文件作为插件的入口
新建完当前目录如下:
三、开发插件
1.在 .vue文件写插件的业务逻辑
<template>
<div v-if="display" id="loadingContainer">
<div class="textContainer">
<div class="loading">
<div class="circle circle1">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="circle circle2">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="circle circle3">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="text">{{ tips }}</div>
</div>
</div>
</template>
<script>
export default {
// 注意name属性,组件的标签就是用这个name属性的值
name: "FullScreenLoadingPlugin",
data() {
return {
display: false,
tips: "",
opTips: "加载中..."
};
},
methods: {
show(tips) {
this.tips = tips || this.opTips;
this.display = true;
},
hide() {
this.display = false;
}
}
};
</script>
<style lang="scss" scoped>
#loadingContainer {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba($color: #000000, $alpha: 0.5);
...
<style>
- 入口文件 .js逻辑
// 引入业务代码的vue组件
import loading from "./FullScreenLoading";
// 定义一个插件的对象
const LoadingPlugin = {
// vue规定插件必须暴露一个 install 方法
// 第一个参数为vue构造器,第二个参数为可选的选项对象
install(Vue, options) {
// 使用vue构造器,Vue.extend()创建一个类
const subClass = Vue.extend(loading);
// 实例化子类,并挂载到HTMLElement实例上
const Profile = new subClass({
el: document.createElement("div")
});
document.body.appendChild(Profile.$el);
// 处理可选的参数
// 在Vue.use(xxx, options)的第二个参数传入tips则会初始化全屏加载中的默认文字
// 例如Vue.use(xxx, { tips: "请稍等..." })
if (options) {
if (options.tips) {
Profile.opTips = options.tips;
}
}
// 添加实例方法,挂载到vue原型上
Vue.prototype.$fullScreenLoading = Profile;
}
};
// 导出对象
export default LoadingPlugin;
js文件中两个方法可以阅读vue官方文档:
到这,组件就开发完成了!
四、本地测试插件
npm run serve
这里我在Home.vue页面测试
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
</div>
</template>
<script>
// @ is an alias to /src
// import HelloWorld from "@/components/HelloWorld.vue";
import Vue from "vue";
import FullScreenLoadingPlugin from "../lib/index";
Vue.use(FullScreenLoadingPlugin);
export default {
name: "Home",
created() {
this.$fullScreenLoading.show("请求中...");
setTimeout(() => {
this.$fullScreenLoading.hide();
}, 2000);
setTimeout(() => {
this.$fullScreenLoading.show();
}, 3000);
}
};
</script>
测试完成继续下一步。
五、打包组件
vue-cli 给我们提供了库文件打包的命令
参考链接:库构建
vue-cli-service build --target lib --name outputName --dest myLib [entry]
// --targe 默认为构建应用,改为 lib 即可启用构建库模式
// --name 后面跟的是输出的文件名称
// --dest 后面跟的是输出目录,默认为dist,这里我改为plugin
// entry: 入口文件,默认src/App.vue,这里我改为 src/lib/index.js
在package.json文件的script中添加一个命令打包插件
"lib": "vue-cli-service build --target lib --name full-screen-loading-plugin --dest plugin src/lib/index.js"
执行命令npm run lib,打包组件
打包完成后,会输出如下文件:
这里有一个坑!
在上面打包完的文件里面 css 和 js 是分离的!导致插件发布到npm后样式丢失!
这里需要增加一个配置,让 css 样式强制内联在输出的 js 里面!
在根目录新建 vue.config.js 文件:
module.exports = {
css: {
extract: false
}
};
这样打包出来就没有css文件了:
这些文件的含义在库构建里面有说明。
六、发布插件到npm
1.在根目录创建文件 .npmignore,忽略发布文件
.DS_Store
node_modules
/dist
/public
/src
babel.config.js
vue.config.js
*.map
*.html
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
2.更改 package.json 文件的信息
记得把 private 属性删除或者改为 false
name:包名,我这里用了带命名空间的;
author:作者;
version:版本号;
description:描述信息;
main:入口文件,这里应该是打包后的入口;
private:是否私有,这里必须是false才能发布到npm,默认false;
keywords:关键词描述。
3.发布
记得切回npm源
nrm use npm
npm login // 登录
npm publish --access public // 发布
发布成功:
npm官网搜索:
七、在项目中使用该组件
npm i @jackycai/full-screen-loading-plugin
main.js
import FullScreenLoadingPlugin from "@jackycai/full-screen-loading-plugin";
Vue.use(FullScreenLoadingPlugin);
// 或者添加自定义配置
Vue.use(FullScreenLoadingPlugin, { tips: "请稍等..." });
项目中调用:
this.$fullScreenLoading.show();
setTimeout(() => {
this.$fullScreenLoading.hide();
}, 2000);
// 也可以在 show 方法中添加自定义的文字
this.$fullScreenLoading.show("全屏插件转圈圈...");
大功告成!