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组件