前言
多个平台都用到的一些公共的功能,又不想用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>
参考文章
个人疑问
如果想将别人已经发布在npm上的插件,封装到自己插件内部使用,除了手动实现该功能,有别的什么更好的方案吗,希望大佬解惑
写在最后
目前该插件已经发布到npm上了,欢迎大家使用
以上就是我将vue插件封装并发布到npm的总结,如有什么疑问欢迎评论留言。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。