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

发布时间:2019-05-29 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【Vue】使用vue封装插件并发布到NPM脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

多个平台都用到的一些公共的功能,又不想用git的子模块,就有了开发成npm插件的想法

放个效果图
clipboard.png

开始动手

因为需求很明确,就是做一个公共的回顶部的插件,所以就使用了简洁版的webpack配置创建工程

vue init webpack-simple x-backtotop
为什么用简洁版,以及简洁版和完整版有什么区别,可以去这篇文章看看
  1. 运行脚本后会让配置一些基础信息,直接确认就行
    clipboard.png
  2. 看看初始化后的目录结构

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

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

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

  4. 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全局注入了你的所有的组件。

  5. 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

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

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

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

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

  8. 修改package.json

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

  9. 发布到npm

    这里就不过多介绍怎么创建npm账号了,在项目根路径下运行

    npm login

    填写用户名密码

    whoami

    确认是否登陆成功,账号是否正确

    npm publish

    最后进行发布就行

发布中可能遇到的问题

  1. no_perms Private mode enable, only admin can publish this module
    原因:因为镜像设置成淘宝镜像了,设置回来即可
    方案:npm config set registry http://registry.npmjs.org
  2. npm publish failed put 500 unexpected status code 401
    原因:一般是没有登录
    方案:重新登陆一次
  3. npm ERR! you do not have permission to publish “your module name”. Are you logged in as the correct user?
    原因:包名被占用
    方案:修改包名即可

发布后的一些修改

发布完成后,想要自己npm run dev,发现报错

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


原因是因为index.html中没有修改资源路径
修改前

<script src="/dist/build.js"></script>

修改后

<script src="/dist/backToTop.js" type="text/javascript"></script>

参考文章

个人疑问

如果想将别人已经发布在npm上的插件,封装到自己插件内部使用,除了手动实现该功能,有别的什么更好的方案吗,希望大佬解惑

写在最后

目前该插件已经发布到npm上了,欢迎大家使用

以上就是我将vue插件封装并发布到npm的总结,如有什么疑问欢迎评论留言。

脚本宝典总结

以上是脚本宝典为你收集整理的【Vue】使用vue封装插件并发布到NPM全部内容,希望文章能够帮你解决【Vue】使用vue封装插件并发布到NPM所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:Vue