【Vue】使用vue封装插件并发布到NPM

10次阅读

共计 3721 个字符,预计需要花费 10 分钟才能阅读完成。

前言
多个平台都用到的一些公共的功能,又不想用 git 的子模块,就有了开发成 npm 插件的想法
放个效果图
开始动手
因为需求很明确,就是做一个公共的回顶部的插件,所以就使用了简洁版的 webpack 配置创建工程
vue init webpack-simple x-backtotop
为什么用简洁版,以及简洁版和完整版有什么区别,可以去这篇文章看看

运行脚本后会让配置一些基础信息,直接确认就行

看看初始化后的目录结构

新建一个 lib 文件夹,存放我们的插件

index.js
import toTop from ‘./x-backToTop.vue’

const comment = {
install: function (Vue) {
Vue.component(toTop.name, toTop)
}
}
// global 情况下 自动安装
if (typeof window !== ‘undefined’ && window.Vue) {
window.Vue.use(comment)
}

export default comment
Tips:此处需要注意的是 install。Vue 的插件必须提供一个公开方法 install,该方法会在你使用该插件,也就是 Vue.use(yourPlugin)时被调用。这样也就给 Vue 全局注入了你的所有的组件。

x-backtotop.vue
<template>
<div class=”backToTop” :style=”‘z-index: ‘ + zIndex” @click=”backToTop” v-show=”bVisible”>
<div class=”icon”></div>
</div>
</template>

<script>
export default {
name: ‘back-to-top’,
props: {
zIndex: {
type: Number,
default: 9999
},
triggerHeight: {
type: Number
},
smooth: {
type: Boolean,
default: true
},
scrollInterval: {
type: Number,
default: 10
},
scrollHeight: {
type: Number,
default: 100
}
},
data () {
return {
interval: null, // 计时器
bVisible: false // 按钮显示状态
}
},
methods: {
resetToTop () {
window.pageYOffset = 0;
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
},
buttonStatus () {
var currentHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
let browserHeight = this.triggerHeight || (window.outerHeight / 4);
this.bVisible = currentHeight > browserHeight;
},
backToTop () {
if (this.smooth) {
var that = this,
_interval = this.scrollInterval,
_height = this.scrollHeight;
// 间隔 {_interval} 移动{_height}
this.interval = setInterval(function () {
that.smoothScroll(_height)
}, _interval)
} else {
this.resetToTop();
}
},
smoothScroll (y) {
if (window.pageYOffset > 0) {
window.pageYOffset = window.pageYOffset – y;
}
if (document.documentElement.scrollTop > 0) {
document.documentElement.scrollTop = document.documentElement.scrollTop – y;
}
if (document.body.scrollTop > 0) {
document.body.scrollTop = document.body.scrollTop – y;
}
var positionNow = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
if (positionNow <= 0) {
clearInterval(this.interval);
// 清除计时器后,全部重置为零,预防回滚为负数时,不再显示的 bug
this.resetToTop();
}
}
},
created () {
window.addEventListener(‘scroll’, this.buttonStatus)
},
destroyed () {
window.removeEventListener(‘scroll’, this.buttonStatus);
}
}
</script>

<style lang=”scss” scoped>
.backToTop {
position: fixed;
right: 100px;
bottom: 150px;
width: 40px;
height: 40px;
size: 40px;
border-radius: 20px;
cursor: pointer;
transition: .3s;
box-shadow: 0 0 6px rgba(0,0,0,.12);
background-color: #FFF;
overflow: hidden;
.icon{
position: absolute;
margin: auto;
left: 0;
top: -8px;
bottom: 0;
right: 0;
width: 0;
height: 0;
border-width: 8px;
border-style: solid;
border-color: transparent #0099CC transparent transparent;
transform: rotate(90deg); /* 顺时针旋转 90°*/
}
}
.backToTop:hover{
box-shadow: 0 0 20px #000;
}
</style>

这里需要注意的有几个点:1. 这里使用的是 addEventListener 而不是 window.onscroll 方法,因为写成 window.onscroll 在离开当前界面的时候,还会触发一次这个监听,虽然没有影响,但是因为不清楚原因,所以使用 addEventListener 方式 2. 使用平滑的移动到顶端,由于我的写法是每隔一段时间减少定高,所以会出现负数的情况,这个时候再怎么滚动,都不会再变更这个值,所以在回到顶部后,将数值重置为 0 3. 这里使用的是 v -show 而不是 v -if,具体区别可以查看下官方文档,简单来说就是经常需要变更的建议用 v -show

插件自测试 我这里是直接在 App.vue 中引用,效果图如下

修改 webpack.config.js,注意的就几个字段

修改 package.json

发布到 npm
这里就不过多介绍怎么创建 npm 账号了,在项目根路径下运行
npm login
填写用户名密码
whoami
确认是否登陆成功,账号是否正确
npm publish
最后进行发布就行

发布中可能遇到的问题

no_perms Private mode enable, only admin can publish this module 原因:因为镜像设置成淘宝镜像了,设置回来即可 方案:npm config set registry http://registry.npmjs.org

npm publish failed put 500 unexpected status code 401 原因:一般是没有登录 方案:重新登陆一次
npm ERR! you do not have permission to publish“your module name”. Are you logged in as the correct user? 原因:包名被占用 方案:修改包名即可

发布后的一些修改
发布完成后,想要自己 npm run dev,发现报错原因是因为 index.html 中没有修改资源路径修改前
<script src=”/dist/build.js”></script>
修改后
<script src=”/dist/backToTop.js” type=”text/javascript”></script>
参考文章

vue 组件篇(2)— 封装组件并发布到 npm
探索 vue-cli 的 webpack 和 webpack-simple 模板的 development server 实现差异

个人疑问
如果想将别人已经发布在 npm 上的插件,封装到自己插件内部使用,除了手动实现该功能,有别的什么更好的方案吗,希望大佬解惑
写在最后
目前该插件已经发布到 npm 上了,欢迎大家使用
以上就是我将 vue 插件封装并发布到 npm 的总结,如有什么疑问欢迎评论留言。

正文完
 0