关于javascript:npmvuecli发布vue自定义组件

40次阅读

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

npm+vue-cli 公布 vue 自定义组件

日常开发中, 咱们常常会封装一些组件, 在多个我的项目切换组件的批改特地麻烦, 咱们能够把这些常常用到的组件公布到 npm 下面进行对立治理, 这样能够大大提高咱们的工作效率, 甚至到前期能够本人封装一套属于本人的组件库;

  1. 应用 vue-cli 疾速创立我的项目
  2. components 目录中创立自定义组件; 上面以 vue-cricleprogressbar 组件为例 CircleProgress.vue

    <template>
      <div class="content" ref="box">
     <svg
       :id="idStr"
       style="transform: rotate(-90deg)"
       :width="width"
       :height="width"
       xmlns="http://www.w3.org/2000/svg"
     >
       <linearGradient :id="`gradient-${id}`" gradientUnits="userSpaceOnUse">
         <stop
           v-for="(item, index) in gradientsColor"
           :key="index"
           :offset="item.offset"
           :stop-color="item.color"
         />
       </linearGradient>
       <circle
         :r="(width-radius)/2"
         :cy="width/2"
         :cx="width/2"
         :stroke-width="radius"
         :stroke="backgroundColor"
         fill="none"
       />
       <circle
         v-if="gradientsColorShow"
         ref="$bar"
         :r="(width-radius)/2"
         :cy="width/2"
         :cx="width/2"
         :stroke="gradientsColor ? `url(#gradient-${id})` : barColor"
         :stroke-width="radius"
         :stroke-linecap="isRound ?'round':'square'":stroke-dasharray="(width-radius)*3.14":stroke-dashoffset="dashoffsetValue"fill="none"
       />
     </svg>
     <div class="center_text">
       <p v-if="!$slots.default" class="title">{{progress}}%</p>
       <slot></slot>
     </div>
      </div>
    </template>
    
    <script>
    // import _ from "lodash";
    export default {
      props: {
     widthPresent: {
       type: Number,
       default: 1
     },
     gradientsColor: {type: [Boolean, Array],
       default: false
     },
     radius: {type: [Number, String],
       default: 20
     }, // 进度条厚度
     progress: {type: [Number, String],
       default: 20
     }, // 进度条百分比
     barColor: {
       type: String,
       default: "#1890ff"
     }, // 进度条色彩
     backgroundColor: {
       type: String,
       default: "rgba(0,0,0,0.3)"
     }, // 背景色彩
     isAnimation: {
       // 是否是动画成果
       type: Boolean,
       default: true
     },
     isRound: {
       // 是否是圆形画笔
       type: Boolean,
       default: true
     },
     id: {
       // 组件的 id,多组件共存时应用
       type: [String, Number],
       default: 1
     },
     duration: {
       // 整个动画时长
       type: [String, Number],
       default: 1000
     },
     delay: {
       // 提早多久执行
       type: [String, Number],
       default: 200
     },
     timeFunction: {
       // 动画缓动函数
       type: String,
       default: "cubic-bezier(0.99, 0.01, 0.22, 0.94)"
     }
      },
      data() {
     return {
       width: 200,
       idStr: "",
       oldValue: 0
     };
      },
      computed: {gradientsColorShow: function() {return true;},
     dashoffsetValue: function() {const { isAnimation, width, radius, progress, oldValue} = this;
       return isAnimation
         ? ((width - radius) * 3.14 * (100 - oldValue)) / 100
         : ((width - radius) * 3.14 * (100 - progress)) / 100;
     }
      },
      watch: {id: function() {this.idStr = `circle_progress_keyframes_${this.id || 1}`;
     },
     progress: function(newData, oldData) {if (newData !== oldData) {
         this.oldValue = oldData;
         this.setAnimation();}
     }
      },
      mounted() {this.idStr = `circle_progress_keyframes_${this.id || 1}`;
     let self = this;
     this.setCircleWidth();
     this.setAnimation();
     // 此处不能应用 window.onresize
     window.addEventListener("resize", function() {self.setCircleWidth();
       self.setAnimation(self);
     });
      },
      methods: {setCircleWidth() {const { widthPresent} = this;
       let box = this.$refs.box;
       let width = box.clientWidth * widthPresent;
       let height = box.clientHeight * widthPresent;
       let cW = width > height ? height : width;
       this.width = cW;
     },
     setAnimation() {
       let self = this;
       if (self.isAnimation) {
         // 反复定义判断
         if (document.getElementById(self.idStr)) {self.$refs.$bar.classList.remove(`circle_progress_bar${self.id}`);
         }
         this.$nextTick(() => {this.startAnimation();
         });
       }
     },
     startAnimation() {
       // 生成动画款式文件
       let style = document.createElement("style");
       style.id = this.idStr;
       style.type = "text/css";
       style.innerHTML = `
       @keyframes circle_progress_keyframes_name_${this.id} {from {stroke-dashoffset: ${((this.width - this.radius) *
         3.14 *
         (100 - this.oldValue)) /
         100}px;}
       to {stroke-dashoffset: ${((this.width - this.radius) *
         3.14 *
         (100 - this.progress)) /
         100}px;}}
       .circle_progress_bar${this.id} {animation: circle_progress_keyframes_name_${this.id} ${this.duration}ms ${this.delay}ms ${this.timeFunction} forwards;}`;
       // 增加新款式文件
       document.getElementsByTagName("head")[0].appendChild(style);
       // 往 svg 元素中增加动画 class
       this.$refs.$bar.classList.add(`circle_progress_bar${this.id}`);
     }
      }
    };
    </script>
    <style  scoped>
    .content {
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .center_text {
      position: absolute;
      color: #1890ff;
      font-size: 22px;
      font-weight: bold;
    }
    </style>
    
  3. 在创立 src/index.js, 这里提供两种办法

    // 办法一, 间接引入组件, 无奈全局注册
    import CircleProgress from './components/CircleProgress.vue';
    export default CircleProgress;
    
    // 办法二, 为组件提供 install 装置办法, 供按需引入
    import CircleProgress from './components/CircleProgress.vue';
    CircleProgress .install = function (Vue) {Vue.component(CircleProgress.name, CircleProgress)
    }
    export default CircleProgress 
  4. 配置 package.json 文件

    {
      "name": "vue-circleprogressbar", // 组件名称
      "version": "1.2.2", // 组件版本号
      "private": false,
      "main": "lib/vue-circleprogressbar.umd.min.js", // 组件入口, 在 scripts.package 命令中生成
      "scripts": {
      "serve": "vue-cli-service serve",
      "build": "vue-cli-service build",
      "lint": "vue-cli-service lint",
      "package": "vue-cli-service build --target lib --name vue-circleprogressbar --dest lib ./src/components/index.js", // 创立 lib 文件夹, 将打包好的组件导入文件夹中
      },
      "keywords": [],
      "author": [],
      "license": "MIT",
      "dependencies": {},
      "devDependencies": {}}

    到这里本地开发工作就根本实现了, 下一步就是把本地组件推送到 npm 下面

  5. 首先须要在 npm 创立一个账号
  6. 在终端执行 npm login 输出你注册的 npm 的账号和明码
  7. 执行 npm publish, 如果没问题的话这里组件就胜利上传到 npm 下面了
  8. 前面就能够像引入其余组件一样间接用 npm install 装置组件进行引入

不分明的能够参考我写的 vue-circleprogressbar 组件源码: vue-circleProgress 组件

正文完
 0