使用npm发布vue组件

😶 NPM 是随同 NodeJS 一起安装的 javascript 包管理工具,能解决 NodeJS 代码部署上的很多问题

发布前的准备

注册一个 npm 账号

前往 NPM 官网进行注册

初始化项目

这里用的是webpack-simple,可以理解为精简版的vue-cli

如果没有全局安装 vue 的话,需要先安装

cnpm i -g  @vue/cli-init

然后再初始化 vue 项目,我们要写的是一个简单的 vue 组件,不需要依赖那么多而庞大的配置,所以,这里我们用简介版本的 webapck 配置模板

vue init webpack-simple 项目名(最好去npm官网搜一下,防止重复)

创建之后的基本目录

创建 vue 插件并发布

创建组件文件夹

举个例子:封装一个返回顶部的小组件

既然是封装组件,那我们在 src 下面创建一个 plugins 文件放我们的插件,但是考虑到万一要写很多个的情况,当前组件的相关文件下创建一个 returnTop 文件夹,下面创建 returnTop.vue 和 index.js 先,结构变成下面这样:

切换到当前根目录,安装依赖,启动项目

cnpm install

cnpm run dev
编写组件代码

示例代码
returnTop.vue

<template>
  <div class="right-return-top">
    <div class="return-top" @click="returnTop" v-show="topShow">
      <img
        src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAAHdbkFIAAAACXBIWXMAAAsSAAALEgHS3X78AAADGUlEQVR4nO2aT2vTYBzHv0/S9aKw7rJz34E5mP6zrRmOjeFgKozBcFAZwkAc6sHrttNgUBBPA5HNi5eBsJPX1k1XT9p3UF/B+g4iadI2ydI0T9P0SfX3hZDmeZI8n9/3efL8acJ0XYefJN/cICckHEfLGR3zCWB+BqjWWSfNYHBsT/O6/diZuaSamW/KvZPCRzEBH5wnPMnp2Ck5y3SE+TiruH2ZAOTQIkKXMM03WM4onYoz5K48m/4BE6kdxOEGCc/UBVXHLQmd7bYM6/cBDmv77lMjrsaNvI7t4u/RbrCaNdDmANzBbnnwTW6MDsam3W3rDzOp3vHLku55XpBec5ioJY6hIYVV6AgIYOoBvLvDQTK6ySQDZhgc+6TkTvPsOr005U/BRl7BVsG3ux6m0RxYzSpIsl+uKmji+EKJFmBBtRc8hy+Ndi/PmMCZbaCJaj04yKBxZuC2pKa4r/HZqCsmAOEA1AgJgAAIgACmaFasqftIsL3+NMxrdmz9PrL+mw0gGoymvBFuFtqo3EuJAVjPG1PyWQDXeF4cGWI0gLVct/A/Vso1XpRGguAHWMl2C2/i8480gGc9iNdlbgg+gMVMv/CzK3P1c/r91AHx9j4XRHAATVV6hZ83nEuvD5d2iHc8AHxLqQdq2jf/VenGCxhamhEAARAAAQyT8J5QtITXgGiRATFgECoyIAYMQkUGxIBBqMiAGDAIFd9L+6DS1DQY0pAZIBs2W3vZtpdcx55pjmtbOKy1xo0ajQFABcDemO95ACDQlxA8orVADBiESqwBm4U0tgqh/t4OKzGPwHpegYQaZDZrdXBNyEzDx8t2gKvHqskasJZTIFuBe48CphHHFxMzYjIGrGT7gfeHQTNYGY8gsxPXMGjmvf8WuRHRGrCYMQOXbIF3gzu7cga3XaxAwolrHtCExDRU65EZEY0BxqsUZqtxyRb4ecM/mJ1SBbLNiO61Rxxfw3EouhZgfOYnsxpktDq1+PUnXy3ulk0jJPYJ1XolGkiaCNFEiAyIAYNQkQExYBAqMiAGDEJFBsSAQaj+bwMA/AVQMPelPAquSAAAAABJRU5ErkJggg=="
      />
    </div>
  </div>
</template>
<script>
  export default {
    name: "ToolReturnTop", //决定引用组件的名称
    data() {
      return {
        scroll: 0,
        topShow: false,
      };
    },
    mounted() {
      window.addEventListener("scroll", this.scrolls);
    },
    methods: {
      returnTop() {
        window.scroll(0, 0);
      },
      scrolls() {
        this.scroll =
          document.documentElement &&
          document.documentElement.scrollTop + document.body.scrollTop;
        if (this.scroll > window.innerHeight / 2) {
          this.topShow = true;
        } else {
          this.topShow = false;
        }
      },
    },
  };
</script>
<style scoped>
  /* 返回顶部 */

  .right-return-top {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 20px;
    z-index: 9;
    margin: auto;
  }

  /* .return-top {
    width: 0.63rem;
    height: 0.63rem;
    z-index: 9;
    margin: 0 auto;
    background-color: #f9f9f9;
    box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
    -webkit-box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
    border-radius: 1rem;
  } */
  .return-top {
    width: 40px;
    height: 40px;
    z-index: 9;
    margin: 0 auto;
    background-color: #f9f9f9;
    box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
    -webkit-box-shadow: 0 0.01rem 0.05rem 0 rgba(0, 0, 0, 0.2) !important;
    border-radius: 1rem;
    -webkit-animation: show 350ms ease-out forwards 1;
    animation: show 350ms ease-out forwards 1;
  }

  .return-top img {
    width: 100%;
    height: 100%;
  }

  @-webkit-keyframes show {
    0% {
      -webkit-transform: rotate(0deg);
    }
    25% {
      opacity: 0.5;
      -webkit-transform: rotate(-3deg) translateY(-0.2rem);
    }
    75% {
      -webkit-transform: rotate(3deg);
    }
    100% {
      opacity: 0.9;
      -webkit-transform: rotate(0deg);
    }
  }

  @keyframes show {
    0% {
      transform: rotate(0deg);
    }
    25% {
      opacity: 0.5;
      transform: rotate(-3deg) translateY(-0.2rem);
    }
    75% {
      transform: rotate(3deg);
    }
    100% {
      opacity: 0.9;
      transform: rotate(0deg);
    }
  }
</style>

编辑 returTop/index.js 文件,目的:将该组件作为 Vue 插件

// sumFunction 插件对应组件的名字
import returnTop from "./returnTop";

// Vue.js 的插件应当有一个公开方法 install 。第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象
// 此处注意,组件需要添加name属性,代表注册的组件名称,也可以修改成其他的
returnTop.install = (Vue) => Vue.component(returnTop.name, returnTop); //注册组件

// 标签的方式引入
//const install = function(Vue, opts = {}) {
//  Vue.component(sumFunction.name, sumFunction);
//}

/* 支持使用标签的方式引入 Vue是全局变量时,自动install */
//if (typeof window !== 'undefined' && window.Vue) {
//  install(window.Vue);
//}

export default returnTop;

此处需要注意的是 install。 Vue 的插件必须提供一个公开方法 install,该方法会在你使用该插件,也就是 Vue.use(yourPlugin)时被调用。这样也就给 Vue 全局注入了你的所有的组件。

在src目录下创建index.js文件,用来统一管理组件

import Vue from 'vue';
import ReturnTop from './plugins/returnTop/index.js';//返回顶部
// ...如果还有的话继续添加
const components = [
  ReturnTop,
]
//循环遍历注册组件,就可以向其他ui组件库那样,使用Vue.use()来全局使用
const install = function (Vue, opts = {}) {
  components.map(component => {
    Vue.component(component.name, component);
  })
}

/* 支持使用标签的方式引入 */
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}


export default {
    install,
    ReturnTop, //在这里多写一次可以单独调用,例如:Vue.use(vueutils.ReturnTop)
}
修改 package.json
{
  "name": "km-vue-utils",
  "description": "vue常用工具合集",
  "version": "0.0.1",
  "author": "SuperKM",
  "license": "MIT",  // 开源协议
  // 采用commonJs入口文件,如果不配置,我们在其他项目中就不用import XX from XX来引用了,只能以包名作为起点来指定相对的路径
  "main": "dist/index.js",
  "jsnext:main": "src/index.js", // 采用es6模块化入口
  "private": false, // 因为组件包是公用的,所以private为false
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
  },
// 指定代码所在的仓库地址
  "repository": {
    "type": "git",
    "url": "https://github.com/superliebe/vueTools.git"
  },
// 提交bug的地址
  "bugs": {
    "url": "https://github.com/superliebe/vueTools/issues"
  },
  // 项目官网的url
  "homepage": "https://github.com/superliebe/vueTools",
  "keywords": [
    "vue",
    "component",
    "tools",
    "superkm"
  ], // 指定关键字
  "dependencies": {
    "vue": "^2.5.11"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "devDependencies": {
   ...
  }
}
修改.gitignore

因为要用 dist 文件夹,所以在.gitignore 文件中把 dist/去掉。

修改 webpack.config.js
// 原
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  }
...
}
// 新
const NODE_ENV = process.env.NODE_ENV
module.exports = {
  entry: NODE_ENV == 'development' ? './src/main.js' : './src/index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'index.js',
    libraryTarget: 'umd', // 指定输出格式
    umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
  }
...

❗ 发布 npm 之前必须做两件事情。

❤️ - 必须 npm run build 打包一下。

❤️ - 必须 修改 package.json 中的版本号。

发布包到 npm

  • 已经注册过 npm 账号,首先登陆,登陆过一次之后,就可以直接发布

npm login --registry http://registry.npmjs.org
//适用于使用了淘宝镜像加速的

//或者

npm login //未采用镜像加速过

输入账号-密码-邮箱后,提示 Logged in as *** on http://registry.npmjs.org/. 就是登陆成功了

  • 然后直接发布
npm publish --registry http://registry.npmjs.org

发布成功后提示,前往自己的 npm 库中就可以查看到刚刚发布的 npm 包

npm 库中

  • 如果想删除发布的包
npm unpublish km-vuetools --force --registry http://registry.npmjs.org
npm 发布中常见错误
  • 409 Conflict

npm login 或者 npm adduser 时 输入完账号密码邮箱后 提示 E409 Conflict 报错 一般因为淘宝镜像的原因

解决方案,直接 registry 镜像源

npm login --registry http://registry.npmjs.org
  • npm ERR! 403

可能是包名已经存在,或者是邮箱未认证

使用自己发布的包

使用 cnpm 安装依赖

cnpm i km-vue-utils -S

在 main.js 文件 或者想要引入的文件导入

import utils from "km-vue-utils";
Vue.use(utils);

在想要引用的.vue 文件中直接写

<!-- 该名称由封装组件中的name属性决定 -->
<tool-return-top></tool-return-top>

<!-- 
 如果想引用组件中包含的方法,给Vue.prototype属性
 Vue.prototype.$utils = utils;
 在需要调用的地方直接写
 this.$utils.方法文件.方法名;
 -->

😜😜😜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值