基于vue-cli快速发布vue npm 包

一、编写组件

1. 初始化项目并运行
vue create vue-digital-count

npm run serve
2. 组件封装
  • 新建package文件夹

​ 因为我们可能会封装多个组件,所以在src下面新建一个package文件夹用来存放所有需要上传的组件。
​ 当然,如果只有一个组件,直接放到src下面也无可厚非。
基于vue-cli快速发布vue npm 包_第1张图片

  • 编写组件代码 digitalCount
    可通过正常组件使用流程引入进行开发、调试
<template>
  <div class="module-count-box"> 
    <div v-for="(site, index) in list" :key="index">
      <div v-if="site.num !== ','" class="site-item">
        <!-- :style 动态移动距离 -->
        <div class="num-list-box" :style="{ top:'-'+site.top+'px' }">
          <p v-for="num in numList" :key="num + '-' + Math.random()" class="num-item">{{ num }}</p>
        </div>
      </div>
      <div v-else class="comma-item">,</div>
    </div>
  </div>
</template>

<script>
  export default {
  	// 必须要有name属性哦,便于后期组件引入并作为组件名
    name: 'VueDigitalCount',
    props: { 
      number: { // 显示的数字
        type: [Number, String],
        default: 0
      },
      showLength: { // 最长显示多少位数字
        type: Number,
        default: 9
      },
      autoFillLength: { // 是否自动用0补齐显示的长度
        type: Boolean,
        default: true
      }
    }, 
    data() { 
      return { 
        list: [], 
        numList: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
      } 
    }, 
    watch: {
      number: {
        handler(newValue, oldValue) {
          this.initNumber()
        },
      }
    },
    mounted() { 
      this.initNumber(true)
    }, 
    methods: { 
      // 在指定位置添加逗号; 参数是字符串
      addCommaToStr(str) {
        let tempArr = str.split('').reverse(); // 实际显示多少位
        for (let i = tempArr.length - 1; i >= 0; i--) {  
          if ((i + 1) % 3 === 0) {  
            tempArr.splice(i + 1, 0, ',');  
          }  
        }
        // 如果最后一个元素为,则删除
        if (tempArr.at(-1) === ',') {
          tempArr.pop();
        }

        // 反过来展示,变成从后面往前,每隔3位加逗号
        return tempArr.reverse();
      },
      // 给数组计算要偏移的高度
      calcMoveHeight(dealArr, isReset) {
        let result = dealArr.map(value => {
          return { num: value }
        }); 
        if (isReset) { // 只有第一次需要重置数据
          result = result.map(item => {
            return {
              ...item,
              top: 0
            }
          })
        }
        
        let itemHeight = 80; // 每一个元素的高度
        result.forEach((value, index) => {
          setTimeout(() => { 
            // value.top = parseFloat((value.num * itemHeight)) || 0; 
            // 使用$set保证数据更新时能触发页面更新
            this.$set(value, 'top', parseFloat((value.num * itemHeight)) || 0)
          }, (index === null ? 0 : index) * 150); // 每个元素间隔150ms去计算偏移的距离
        }); 
        return result;
      },
      initNumber(isReset = false) {
        let fillContent = ''; // 前面填充的字符串(全是0)
        const numStr = this.number.toString(); // 将props转成字符串
        let showNumber = numStr; // 最终展示的字符串,默认就是传过来的数据
        if (this.autoFillLength) { // 需要自动填充
          if (numStr.length < this.showLength) { // 小于指定显示的位数
            fillContent = new Array(this.showLength - numStr.length).fill(0).join(''); // 生成指定位数的0的数组并转化为字符串
          }
          showNumber = fillContent + showNumber; // 在前面填充0,达到指定位数
        }

        // 通过方法,往字符串里添加逗号
        const resultArr = this.addCommaToStr(showNumber);

        // 计算每个数字需要滚动的距离
        this.list = this.calcMoveHeight(resultArr, isReset);
      },
    } 
  }
</script>

<style scoped>
.module-count-box {
  display: flex;
}
.module-count-box .site-item { 
  width: 66px; 
  height: 80px; 
  overflow: hidden;
  text-align: center; 
  display: flex;
  margin: 0 4px; 
  background: url("@/assets/count_num_bg.png") no-repeat;
  background-size: 100% 100%; 
  position: relative; 
}
.module-count-box .site-item .num-list-box {
  position: absolute; 
  top: 0; 
  left: 0; 
  transition: all 1.5s ease-in-out 0s;
  /* top: -80px; */
} 
.module-count-box .site-item .num-list-box > .num-item {
  width: 66px; 
  height: 80px; 
  font-size: 56px;
  font-weight: 600;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0px;
  color: #fff
}

.module-count-box .comma-item {
  font-size: 100px;
  color: #BBD7FF;
  margin-top: -26px;
}
</style>
3. 使用vue插件模式

该步骤时组件封装的重点,即利用vue的公开方法: install
install 方法会在你使用 Vue.use(plugin) 时被调用,这样使得我们的插件注册到了全局,在子组件的任何地方都可以使用。

在package目录下新建index.js文件,代码如下:

// 1. 引入组件
import VueDigitalCount from './digitalCount';

// 2. 用数组保存组件,便于遍历
const components = { VueDigitalCount };

// 3. 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
const install = function (Vue) {
  // 判断是否安装
  if (install.installed) return;
  install.installed = true; //标识已经安装
  // 遍历并注册全局组件
  Object.keys(components).forEach(key => {
    Vue.component(key, components[key]);
  });
}

// 对于那些没有在应用中使用模块化系统的用户(如在html中直接使用vue),他们往往将通过 
                    
                    

你可能感兴趣的:(工具,vue.js,npm,前端)