发布一个属于自己的NPM包(vue 按需引入)

前言

在项目开发中,我们经常会遇到公共部分,我们会在此项目中封装为一个公用的组件,但是如果有其他项目也需要用到该组件,就需要复制粘贴,费时费力;此时我们只需要自己发布一个组件或组件库,将项目中同类型的组件封装在组件库,并通过NPM安装使用
相关文章:发布一个属于自己的NPM包(vue 全局引入)

github地址:github.com/luochenya/n...

npm地址:www.npmjs.com/package/luo...

准备

一、注册属于自己的NPM账号 点击前往NPM官网

二、环境配置

npm => 9.3.1

node => 20.9.0

使用

一、创建一个基础的vite脚手架

bash 复制代码
npm create npm-package

按提示进行安装依赖,启动项目

二、删除无用文件

  1. 删除 src/assets 文件夹
  2. 删除 src/components 文件夹
  3. 清空 App.vue 文件内容

三、封装组件

1、创建组件对应文件 src/package/luochenya-button/index.vue ,文件目录如下:

2、写入封装组件代码,内容如下:

js 复制代码
<template>
  <button @click="confirmEvent">
    <slot />
  </button>
</template>

<script>
  import { h, defineComponent, computed } from 'vue'
  export default defineComponent({
    name: "luochenya-button",
    emits: ['confirm'],
    props: {
      
    },
    setup(props, { emit }) {
      const confirmEvent = () => {
        emit('confirm')
      }
      return {
        confirmEvent
      }
    }
  })
</script>

<style scoped>
  button {
    z-index: 1;
    position: relative;
    font-size: inherit;
    font-family: inherit;
    color: white;
    padding: 0.5em 1em;
    outline: none;
    border: none;
    background-color: hsl(236, 32%, 26%);
    overflow: hidden;
    transition: color 0.4s ease-in-out;
  }
  
  button::before {
    content: "";
    z-index: -1;
    position: absolute;
    top: 100%;
    right: 100%;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    background-color: #3cefff;
    transform-origin: center;
    transform: translate3d(50%, -50%, 0) scale3d(0, 0, 0);
    transition: transform 0.45s ease-in-out;
  }
  
  button:hover {
    cursor: pointer;
    color: #161616;
  }
  
  button:hover::before {
    transform: translate3d(50%, -50%, 0) scale3d(15, 15, 15);
  }
</style>  

3、引入到 App.vue 里验证一下,看组件是否可用,内容如下:

js 复制代码
<script>
  import { defineComponent } from "vue";
  import LuoChenYaButton from "./package/luochenya-button/index.vue";

  export default defineComponent({
    components: {
      LuoChenYaButton
    },
    methods: {
      handleClick() {
        console.log("click");
      }
    }
  })
</script>

<template>
  <LuoChenYaButton @confirm="handleClick">test按钮</LuoChenYaButton>
</template>

4、导出组件,创建 src/package/index.js 文件,内容如下:

js 复制代码
import LuoChenYaButton from "../package/luochenya-button/index.vue";
export { LuoChenYaButton };

四、封裝方法

1、创建方法对应文件,文件目录如下:

2、写入封装方法代码,内容如下:

src/package/luochenya-js/scroll.js 滚动相关js

js 复制代码
/**
 * @Description 禁用滚动条
 * @Author luochen_ya
 * @Date 2025-01-11
 */
export function handleStopScroll () {
  var mo = function (e) { e.preventDefault() }
  document.body.style.overflow = 'hidden'
  document.addEventListener("touchmove", mo, false)
}

/**
 * @Description 恢复滚动条
 * @Author luochen_ya
 * @Date 2025-01-11
 */
export function handleCanScroll () {
  var mo = function (e) { e.preventDefault() }
  document.body.style.overflow = ''
  document.removeEventListener("touchmove", mo, false)
}

src/package/luochenya-js/thousands.js 千位符相关js

js 复制代码
/**
 * @Description 數字千位符
 * @Author luochen_ya
 * @Date 2025-01-11
 * @param {number} value
 * @returns {string}
 */
export function handleThousands (value) {
  const suffix = ''
  if (value && value !== 'NULL' && value !== 'undefined' && isNaN(Number(value))) {
    return value
  } else if (!value) {
    return '0'
  } else {
    const pSuffix = ''
    value = value.toString()
    const intPart = Math.floor(Math.abs(Number(value)))
    let intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
    intPartFormat = pSuffix + intPartFormat
    let floatPart = ''
    const value2Array = value.split('.')
    
    if (value2Array.length === 2) {
      floatPart = value2Array[1].toString()
      if (floatPart.length === 1) {
        
        return intPartFormat + '.' + floatPart + '0' + suffix
      } else {
        return intPartFormat + '.' + floatPart + suffix
      }
    } else {
      return intPartFormat + floatPart + suffix
    }
  }
}

src/package/luochenya-js/index.js 统一导出相关js

js 复制代码
import { handleStopScroll, handleCanScroll } from './scroll.js';
import { handleThousands } from './thousands.js';
export default { handleStopScroll, handleCanScroll, handleThousands };

3、引入到 App.vue 里验证一下,看方法是否可用,内容如下:

js 复制代码
<script>
  import { defineComponent } from "vue";
  import LuoChenYaButton from "./package/luochenya-button/index.vue";
  import LuoChenYaJs from "./package/luochenya-js/index.js";

  export default defineComponent({
    components: {
      LuoChenYaButton
    },
    methods: {
      handleClick() {
        const { handleThousands } = LuoChenYaJs;
        console.log(handleThousands(1234567890));
      }
    }
  })
</script>

<template>
  <LuoChenYaButton @confirm="handleClick">test按钮</LuoChenYaButton>
</template>

4、导出组件,创建 src/package/index.js 文件,内容如下:

js 复制代码
import LuoChenYaJs from "../package/luochenya-js/index.js";

export { LuoChenYaJs };

五、打包组件

1、在 package.json 文件下配置打包命令,内容如下:

"package": "vue-cli-service build --target lib ./src/package/index.js --name luochenya-common --dest luochenya-common"

打包命令解释:

1、--target lib 指定打包的目录

2、--name 打包后的文件的名称

3、--dest 打包后的文件夹的名称

2、执行打包命令 npm run package ,打包后会多出一个 luochenya-common 文件夹,结构如下:

六、发布到NPM

1、 初始化package.json

luochenya-common 文件夹下执行命令 npm init -y,会多出一个 package.json 文件,可以配置发布的包名、版本号、版本描述,内容如下:

bash 复制代码
npm init -y

2、设置NPM源

如果有设置了淘宝镜像的需要切换源,切换命令如下:

bash 复制代码
npm config set registry=https://registry.npmjs.org

3、添加NPM用户

luochenya-common 文件夹下执行命令 npm adduser ,根据提示去输入账号、密码,如果之前有设置则跳过此步

4、发布NPM

luochenya-common 文件夹下执行命令 npm publish ,如果发布失败可能是名字重复,改一下名字即可,发布成功后,我们可以到NPM官网上查看自己发布的NPM包

七、从NPM安装并使用

1、安装

bash 复制代码
npm install luochenya-common

2、全局引用注册

1、main.js 引用注册,内容如下:
js 复制代码
import { LuoChenYaButton, LuoChenYaJs } from "luochenya-common"; //引入包
import "../node_modules/luochenya-common/luochenya-common.css"; //引入包样式

const app = createApp(App);
app.component('LuoChenYaButton', LuoChenYaButton);
app.config.globalProperties.LuoChenYaJs = LuoChenYaJs; //公共方法
app.mount('#app')
2、使用组件、方法
js 复制代码
<script>
import { getCurrentInstance, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const { proxy } = getCurrentInstance();
    const { handleThousands } = proxy.LuoChenYaJs;
    return { handleThousands };
  },
});
</script>

<template>
  <LuoChenYaButton>test按钮</LuoChenYaButton>

  <h4>千位符:{{ handleThousands(1234567890) }}</h4>
</template>

2、按需引用注册

1、页面使用,内容如下:
js 复制代码
<script>
import { LuoChenYaButton, LuoChenYaJs } from "luochenya-common"; //引入包
import "luochenya-common/luochenya-common.css"; //引入包样式
import { defineComponent } from "vue";
export default defineComponent({
  components: {
    LuoChenYaButton,
  },
  methods: {
    handleClick() {
      const { handleThousands } = LuoChenYaJs;
      console.log(handleThousands(1234567890));
    }
  }
});
</script>

<template>
  <LuoChenYaButton @confirm="handleClick">test按钮</LuoChenYaButton>
</template>
相关推荐
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端