• 发布自己第一个npm 组件包(基于Vue的文字跑马灯组件)


    一、前言

    总结下最近工作上在移动端实现的一个跑马灯效果,最终效果如下:

    888.gif

    印象中好像HTML标签的‘marquee’的直接可以实现这个效果,不过 HTML标准中已经废弃了‘marquee’标签
    既然HTML标准已经废弃了这个标签,现在工作上用的是Vue,所以想着能不能自己也发布一个基于Vue的文字跑马灯组件包,这样别人可以通过npm install ...就可以用,想想还有点激动,于是开始我的第一个npm组件之旅!

    二、用npm发布一个包

    有点惭愧,之前通过npm install ...安装package包时,我是不知道package包存在哪里,在github上?折腾一番才知道是在npm上发布的。

    2.1 npm发布包流程

    1. 进入官网,注册帐号
      如图

    2. 进入已经写好的组件, 登录npm帐号
      如图

    3. 执行npm publish,最先遇到问题好像是这个
      如图

      这里注意的是因为国内网络问题,许多小伙伴把npm的镜像代理到淘宝或者别的地方了,这里要设置回原来的镜像。npm config set registry=http://registry.npmjs.org

      后面又遇到

      如图

      这里我还特意查了下ENEEDAUTH错误,可是却没看后面的提示:You need to authorize this machine using 'npm adduser'
      所以这里需要npm adduser
      如图
      (发布的包的名字也要注意,有可能会有重名问题,像我这个组件包本来取名为vue-marquee,后面在npm上搜到已经有这个包了,不过他做的是垂直方向的跑马灯。所以我把这个为了区分这个组件包是水平方向的,改名为vue-marquee-ho)

    三、基于Vue的文字跑马灯组件

    大致了解怎么发组件包以后,我们再来看看需要发布出去的组件包怎么写的。

    3.1初始化组件

    这里我还是用到vue-cli,虽然有很多东西不需要,因为对这个比较熟悉,所以还是按照这个步骤来,初始化该组件

    vue init webpack vue-marquee-ho
    cd vue-marquee-ho
    cnpm install // 安装依赖包
    npm run dev // 启动服务
    

    3.2修改配置文件

    首先看package.json

      "name": "vue-marquee-ho",
      "version": "1.2.1",
      "description": "A Vue component to marquee",
      "author": "wangjuan",
      "private": false,
      "license": "MIT",
      "main": "dist/vue-marquee.min.js",
      "scripts": {
        "dev": "node build/dev-server.js",
        "start": "node build/dev-server.js",
        "build": "node build/build.js",
        "test": "node build/test.js"
      },
      "dependencies": {
        "vue": "^2.2.6"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/wj704/vue-marquee-ho.git"
      },
    

    因为这个组件包是能公用的,所以"private": false,
    然后 "main": "dist/vue-marquee.min.js", 这里的配置意思是,别人用这个包 import VueMarquee from 'vue-marquee-ho'; 时,引入的文件。
    可以看出,这个vue-marquee-ho最终需要打包出一个js文件,所以我们需要修改webpack.prod.config.js文件

    var webpackConfig = merge(baseWebpackConfig, {
      module: {
        rules: utils.styleLoaders({
          sourceMap: config.build.productionSourceMap,
          extract: true
        })
      },
      devtool: config.build.productionSourceMap ? '#source-map' : false,
      // output: {
      //   path: config.build.assetsRoot,
      //   filename: utils.assetsPath('js/[name].[chunkhash].js'),
      //   chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
      // },
       output: {
        path: config.bundle.assetsRoot,
        publicPath: config.bundle.assetsPublicPath,
        filename: 'vue-marquee.min.js',
        library: 'VueMarquee',
        libraryTarget: 'umd'
      },
      plugins: [
        // http://vuejs.github.io/vue-loader/en/workflow/production.html
        new webpack.DefinePlugin({
          'process.env': env
        }),
        new webpack.optimize.UglifyJsPlugin({
          compress: {
            warnings: false
          },
          sourceMap: true
        }),
        // extract css into its own file
        new ExtractTextPlugin({
          // filename: utils.assetsPath('css/[name].[contenthash].css')
           filename: 'vue-marquee.min.css'
        }),
        new OptimizeCSSPlugin()
      ]
    })
    module.exports = webpackConfig
    

    可以看到我的output输出配置改了下,然后有很多webpack.prod.config.js之前不需要的代码去掉了,再看下对应的config配置,文件是config/index.js

    bundle: {
        env: require('./prod.env'),
        assetsRoot: path.resolve(__dirname, '../dist'),
        assetsPublicPath: '/',
        assetsSubDirectory: '/',
        productionSourceMap: true,
        productionGzip: false,
        productionGzipExtensions: ['js', 'css'],
        bundleAnalyzerReport: process.env.npm_config_report
      },
    

    至此配置差不多修改好了。接下来我们看看实现关键功能的Marquee组件

    3.3 Marquee组件

    思路:标签里的文字所占的宽度超过外面的div宽度时,增加一个内容相同的标签。这里span标签设置为display: inline-block;,可以计算其宽度,把span标签外面的父元素设置为font-size: 0;display: inline-block;,父级元素的宽度即为两者宽度之和,也就是一个span标签宽度的两倍,然后将其父级元素通过CSS3动画设置:

    @keyframes marquee {
        0%  { transform: translateX(0); }
        100% { transform: translateX(-50%);}
    }
    

    即可完美实现跑马灯效果。
    具体代码:

    <template>
      <div class="marquee-box">
        <div class="marquee-content" ref="out">
          <p :class="run?speed:''">
            <span class="text1" ref="in" >{{content}}</span>
            <span class="text2" v-if="showtwo||run">{{content}}</span>
          </p>
        </div>
      </div>
    </template>
    

    js:

    <script>
      export default {
        name: 'VueMarquee',
        data (){
          return{
            run: false,
            pWidth: '',
          }
        },
        props: {
          content: {
            default: "暂无内容",
            type: String
          },
          speed: {
            default: 'middle',
            type: String
          },
          showtwo: {
            default: true
          }
        },
        mounted (){
          // let out = document.getElementById(this.pid.out).clientWidth;
          // let _in = document.getElementById(this.pid.in).clientWidth;
          var _this = this;
          this.$nextTick(()=>{
            let out = _this.$refs.out.clientWidth;
            let _in = _this.$refs.in.clientWidth;
            _this.run=_in>out?true:false;
          });
        }
      }
    </script>
    
    

    css:

    <style>
      .marquee-box {
        height: 50px;
        line-height: 50px;
        color: #000;
        font-size: 24px;
        background-size: 24px 24px;
      }
      .marquee-content{
        overflow: hidden;
        100%
      }
      .marquee-content p{
        display: inline-block;
        white-space: nowrap;
        margin: 0;
        font-size: 0;
      }
      .marquee-content span{
        display: inline-block;
        white-space: nowrap;
        padding-right: 40px;
        font-size: 24px;
      }
      .quick{
        -webkit-animation: marquee 5s linear infinite;
        animation: marquee 5s linear infinite;
      }
      .middle{
        -webkit-animation: marquee 8s linear infinite;
        animation: marquee 8s linear infinite;
      }
      .slow{
        -webkit-animation: marquee 25s linear infinite;
        animation: marquee 25s linear infinite;
      }
      @-webkit-keyframes marquee {
        0%  { -webkit-transform: translate3d(0,0,0); }
        100% { -webkit-transform: translate3d(-50%,0,0); }
      }
      @keyframes marquee {
        0%  { transform: translateX(0); }
        100% { transform: translateX(-50%);}
      }
    </style>
    

    我们知道 webpack.base.conf.js 中入口文件默认指定为:

    entry: {
        app: './src/main.js'
      },
    

    所以,我们只需要将main.js引入Marquee.vue组件就可以。有两种方式引入:

    import VueMarquee from './Marquee.vue'
    export default VueMarquee;
    
    // var VueMarquee = require('./Marquee.vue');
    // module.exports = VueMarquee
    

    注意import 和module.exports不要一起用,github看到其他人提交的组件是这两个一起用的,这样在windows下会报错,好像mac不会有问题。

    3.4 打包生成dist/vue-marquee.min.js

    通过npm run build 即可看到目录下生成了dist文件,dist文件里有四个文件,分别是:

    vue-marquee.min.js
    vue-marquee.min.js.map
    vue-marquee.min.css
    vue-marquee.min.css.map
    

    我们知道有一个这样的文件.gitignore,里面包含npm install时,不会安装的东西,因为这里要用到dist文件,于是我把.gitignore 里的dist/去掉了。

    .DS_Store
    node_modules/
    
    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*
    

    打包好了后,通过npm publish 提交到npm上

    如图

    需要多次提交时注意修改package.json中的"version": "1.2.1", 我这里已经提交了21次了(捂脸哭(┬_┬))

    四、使用组件

    通过npm install vue-marquee-ho -s 安装到相应的项目下,安装成功如下图所示:

    如图

    到项目中的node_modules/目录下将可以看到:

    如图

    需要用到该组件时可以这样引入(注意引入样式)

    import VueMarquee from 'vue-marquee-ho';
    import Css from 'vue-marquee-ho/dist/vue-marquee.min.css'
    export default {
      name: 'app',
      components:{
          "vue-marquee": VueMarquee
        },
    }
    

    看一个demo:

    <template>
      <div id="app">
        <div class="marquee-wrap" style=" 100px;"><vue-marquee content="33333" class="two"  :showtwo="false"></vue-marquee></div>
        <div class="marquee-wrap" style=" 100px;"><vue-marquee content="22222" class="two"  :showtwo="false"></vue-marquee></div>
        <div class="marquee-wrap" style=" 100px;"><vue-marquee content="1" class="two"  :showtwo="false"></vue-marquee></div>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    import VueMarquee from 'vue-marquee-ho';
    import Css from 'vue-marquee-ho/dist/vue-marquee.min.css'
    export default {
      name: 'app',
      components:{
          "vue-marquee": VueMarquee
        },
    }
    </script>
    

    效果:

    如图

    五、总结

    总算发布出去,能正常使用了!花了挺多时间的,虽然这个组件思路比较简单,但是说不定别人能用上呢。这个组件的雏形代码比现在多,不过之前在项目中直接引用也能正常使用。但是把他打包发布出去再使用的过程,出了很多问题,反复修改代码,精简代码,最终终于成功了!21次的提交记录,不容易呀,源代码地址:

    vue-marquee-ho

    希望能得到大家的star _

    参考资料:
    1、http://www.jianshu.com/p/36d3e0e00157
    2、http://www.cnblogs.com/marymei0107/p/6339710.html
    3、http://blog.csdn.net/gamesdev/article/details/49018629
    4、https://segmentfault.com/a/1190000006250554
    5、https://stackoverflow.com/questions/
    6、http://www.mamicode.com/info-detail-1694072.html
    7、http://blog.csdn.net/crper/article/details/50722753 (虽然调试技巧我还是没学会(✿◡‿◡))
    8、https://github.com/xiaokaike/vue-color
    9、https://github.com/li-xianfeng/vue-marquee

  • 相关阅读:
    1254:走出迷宫
    1332:【例2-1】周末舞会
    P1744 采购特价商品 题解(讲解图论)
    p1305 新二叉树
    P1069 细胞分裂
    LOJ #124. 除数函数求和 1
    P4438 [HNOI/AHOI2018]道路
    P4318 完全平方数
    P1447 [NOI2010]能量采集
    P3200 [HNOI2009]有趣的数列
  • 原文地址:https://www.cnblogs.com/wj204/p/6868375.html
Copyright © 2020-2023  润新知