Vue2封装一个全局通知组件并发布到NPM

news2024/11/16 13:53:30

✍🏼作者:周棋洛,计算机学生
♉星座:金牛座
🏠主页:点击查看更多
🌐关键:vue2 组件封装 npm发包

在这里插入图片描述

文章目录

  • 1. 前言 🍃
  • 2. 我为什么要封装通知插件 ❓
  • 3. 初始化vue空项目 💻
  • 4. 通知组件封装 ⏰
    • 4.1 整理项目结构 📖
    • 4.2 基础结构搭建 🌳
    • 4.3 字体图标引入 🎄
    • 4.4 修改组件结构 🍕
    • 4.5 插件核心逻辑 🍉
    • 4.6 美化通知样式 🌂
    • 4.7 实现通知方法 🚥
    • 4.8 实现两个方法 🥛
    • 4.9 修改固定模板 🏜️
  • 5. 测试组件 🛠️
  • 6. 打包组件 📦
    • 6.1 编写打包命令 ⌨️
    • 6.2 整理打包文件 📄
    • 6.3 生成 package.json 📁
    • 6.4 修改 package.json 📁
    • 6.5 README.md文件 📃
  • 7. 发布组件 🎉
    • 7.1 账号注册 📱
    • 7.2 检查源 ⛏️
    • 7.3 添加用户 🧑‍🎄
    • 7.4 推送 ⏏️
    • 7.5 更新版本 ✅
    • 7.6 删除包 ❗
  • 8. 安装自己编写的组件 😀
  • 9. 总结 📄

1. 前言 🍃

你好!我是王子周棋洛,好久没写文了。

今天带大家 封装 一个类似 element-ui 的全局通知组件,并发布到 npm 后安装使用自己封装的组件。go,go,go🎉

在这里插入图片描述

2. 我为什么要封装通知插件 ❓

原因1:现成UI组件不适合我。

我之前使用 element-ui 组件库时,它的通知组件调用方式是传入配置对象。代码如下:

this.$notify({
    title: '警告',
    message: '这是一条警告的提示消息',
    type: 'warning'
});

可能官方考虑到配置项很多,就采用了配置对象的形式,但是我写一些小型网站时,这样写显得非常麻烦

首先呢,如果写一行,代码可读性很差。如果写多行,显得很冗余

其次,配置对象,每次都要写重复的对象名,比如:title,message,type,这对于简单的通知来说显得很不友好!当然更加复杂的通知,采用配置对象的形式是没问题的。

因为对我来说通知是一个频繁使用的组件。于是我改用了函数式调用,通过函数声明通知类型,参数限制至多三个,不然函数式就意义不大了。下面是本组件最终的调用代码:

this.$notify.success("成功消息");

我想说对于要求不多的通知组件,这样的api,一行就是一个消息,才是我想要的,哈哈。

其次还有个原因,我在写网站时,或者软件都会用到通知组件,我每次都是搬代码,太不优雅了,于是,我就去了解了一下 npm发包 我已经发布到了npm。

学完本篇文章,你将学会如何封装一个全局消息组件,并学会发布你编写的组件到互联网,这是很有成就感的事情哦,快学起来吧!

npm地址:https://www.npmjs.com/package/zhouql-notify

在这里插入图片描述

在这里插入图片描述

3. 初始化vue空项目 💻

使用vue-cli初始化一个vue空项目。

vue create app

这里只使用了一个css框架 less。

在这里插入图片描述

在这里插入图片描述

4. 通知组件封装 ⏰

以下是项目初始化后 package.json 文件的信息。

在这里插入图片描述

4.1 整理项目结构 📖

首先呢,我们需要整理一下项目结构,以及修改一下基础配置。

打开 App.vue 文件,把不需要的内容删除。

删除前:

在这里插入图片描述

删除后:

在这里插入图片描述

删除默认组件 HelloWorld.vue

在这里插入图片描述

打开 vue.config.js ,添加如下配置。

  lintOnSave: false, // 关闭eslint检查
  productionSourceMap: false, // 生产环境是否要生成 sourceMap
  publicPath: './',  // 部署应用包时的基本 URL
  assetsDir: 'assets',  // 放置静态文件夹目录

在这里插入图片描述

好了,整理工作完成,下面着手封装组件。

4.2 基础结构搭建 🌳

components 文件夹下新建一个 notify 文件夹作为组件的文件夹,然后在 notify文件夹 下新建一个 Notify.vue 单文件组件和一个入口 index.js 文件,如下:

在这里插入图片描述

Notify.vue

写一下基础结构,一个div盒子,里面有一个字体图标用来标记消息类型和一个通知内容。

<template>
  <div class="z-notify">
    <!-- icon字体图标,消息类型 -->
    <i></i>
    <!-- 消息内容 -->
    <span></span>
  </div>
</template>

<script>
export default {
  name: "notify"
}
</script>

<style lang="less">
</style>

4.3 字体图标引入 🎄

我是在 iconfont.cn 网站找的图标,大家可以根据需要自行选择。

在这里插入图片描述

因为有彩色图标,可以修改项目设置,下图是我的配置供参考。

在这里插入图片描述

选完图标之后,下载到本地即可,然后解压后打开,只需要我下图框选的几个文件就可以了。

在这里插入图片描述

components 文件夹下新建一个 fonts 文件夹用来存放字体图标,然后将上面框选的文件复制粘贴到文件夹下。如下:

在这里插入图片描述

Notify.vue

引入字体图标:

<style lang="less">
// 引入字体图标
@import url("../fonts/iconfont.css");
</style>

好了,至此字体图标已经完成了。

4.4 修改组件结构 🍕

下面我们简单修改一下 Notify.vue ,因为我之前字体图标修改了配置,就是这两个:

在这里插入图片描述

所以我在使用是类名是 zfont z-chenggong ,这里需要注意一下。

<template>
  <div class="z-notify">
    <!-- icon字体图标,消息类型 -->
    <i class="zfont z-chenggong"></i>
    <!-- 消息内容 -->
    <span>你好,通知组件</span>
  </div>
</template>

<script>
export default {
  name: "notify"
}
</script>

<style lang="less">
// 引入字体图标
@import url("../fonts/iconfont.css");
</style>

4.5 插件核心逻辑 🍉

编写 notify 文件夹下的 index.js 入口文件,首先定义一个全局变量避免组件多次创建,然后实现 install 方法,因为 Vue.use() 会调用 install ,那自然我们就可以在 intsall 方法参数里获取到 Vue实例了。

我们通过 Vue.extend 创建一个组件构造器,传入之前编写好的组件 Notify.vue ,这样组件构造器就定义好了,使用 new 关键字对组件进行实例化得到一个组件实例 notifyInstanse

然后将组件实例挂载到DOM,至此插件的核心逻辑就完成了。

import Notify from './Notify.vue'

// 单实例
let notifyInstanse = null;

const NotifyPlugin = {
    install(Vue) {
        if (!notifyInstanse) {
            // Vue.extend() 方法创建了一个名为 NotifyComponent 的组件构造器。
            // 传入的参数是一个名为 Notify 的 Vue 组件。这个组件定义了通知组件的模板、样式和行为。
            // 只不过是组合了一下组件创建。
            const NotifyComponent = Vue.extend(Notify);
            // new NotifyComponent() 创建一个 notifyInstanse 对象,表示一个通知组件实例。
            notifyInstanse = new NotifyComponent();
            // 将通知组件挂载到DOM中
            const container = document.createElement("div");
            document.body.appendChild(container);
            notifyInstanse.$mount(container);
        }
    }
}

export default NotifyPlugin

下面我们在 main.js 中引入插件并使用。

import Vue from 'vue'
import App from './App.vue'

import NotifyPlugin from './components/notify'
Vue.use(NotifyPlugin)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

启动项目并在浏览器打开,可以看到组件成功挂在到DOM。

在这里插入图片描述

4.6 美化通知样式 🌂

好嘞,下面呢,就是编写一下组件的样式和动画,基础的css知识,下面是完整的css代码,使用了固定定位并做了居中处理,top:-32px;用于初始化时隐藏通知,因为使用者传入的通知可能很长,这时候需要处理,我这里限制了通知最宽为70%,如果文字超了则隐藏并显示三个小点,具体代码是这样:

// 超出隐藏
overflow: hidden;
// 文字超出显示省略号
text-overflow: ellipsis;
// 不换行
white-space: nowrap;

因为字体图标大小表现不一,所以我对字体图标做了单独的大小调整,使得整体协调,最后定义了加载字体图标的旋转动画,为了方便使用动画,我定义了一个类名 rotate-icon

<style lang="less">
// 引入字体图标
@import url("../fonts/iconfont.css");
.z-notify {
  // 固定定位并居中
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  // 默认隐藏
  top: -32px;
  height: 30px;
  max-width: 70%;
  line-height: 30px;
  text-align: center;
  background: #e8e8e8;
  padding: 0px 16px;
  border-radius: 30px;
  transition: transform 0.55s;
  display: flex;
  align-items: center;
  i {
    display: block;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    margin-left: -5px;
    &::before {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 15px;
      height: 15px;
    }
  }

  span {
    color: #213547;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    user-select: none;
    padding-left: 4px;
    font-size: 13px;
    vertical-align: middle;
  }

  // 字体图标大小表现不一,微调
  .z-jiazai_shuang {
    font-size: 17px;
  }

  .z-chenggong {
    font-size: 13px;
  }
  .z-icon-test1 {
    font-size: 15px;
  }
  .z-jinggao {
    font-size: 15px;
  }
  .z-tongzhi {
    font-size: 13px;
  }
  .z-bug {
    font-size: 14px;
  }
  .z-kaixin {
    font-size: 14px;
  }
  .z-yinliao2 {
    font-size: 15.5px;
  }
  .z-jiazai1 {
    font-size: 20px;
  }
  .z-jiazai3 {
    font-size: 15px;
  }
  .z-jiazai2 {
    font-size: 13px;
  }
}

// 加载时的字体图标动画
@keyframes rotate-icon {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(1turn);
  }
}

// 加载时的字体图标类名
.rotate-icon {
  animation: rotate-icon 0.85s linear infinite;
}
</style>

最终效果是这样的:

在这里插入图片描述

4.7 实现通知方法 🚥

还记得在实现插件核心逻辑时的 intsall 方法吗?

install(Vue) {
}

我们想通过 this.$notify.success("成功消息") 这样的方式调用,上面可以拿到Vue实例了,是不是给实例原型添加属性就可以了。

// 添加全局方法
Vue.prototype.$notify = {
    success(message, duration) {
        notifyInstanse.showNotify(message, 'success', duration);
    },
    warning(message, duration) {
        notifyInstanse.showNotify(message, 'warning', duration);
    },
    info(message, duration) {
        notifyInstanse.showNotify(message, 'info', duration);
    },
    error(message, duration) {
        notifyInstanse.showNotify(message, 'error', duration);
    },
    loading(message, duration = 1000 * 60 * 60 * 24) {
        if (arguments.length == 1) {
            notifyInstanse.showNotify(message, 'loading', 1000 * 60 * 60 * 24);
            return
        }
        if (typeof arguments[1] == 'string') {
            notifyInstanse.showNotify(message, 'loading', 1000 * 60 * 60 * 24, arguments[1]);
            return
        }
        if (typeof arguments[1] == 'number') {
            if (typeof arguments[2] == 'string') {
                notifyInstanse.showNotify(message, 'loading', duration, arguments[2]);
            } else {
                notifyInstanse.showNotify(message, 'loading', duration);
            }
        }

    },
    bug(message, duration) {
        notifyInstanse.showNotify(message, 'bug', duration);
    },
    happy(message, duration) {
        notifyInstanse.showNotify(message, 'happy', duration);
    },
    free(message, duration) {
        notifyInstanse.showNotify(message, 'free', duration);
    },
    close() {
        notifyInstanse.closeNotify();
    }
}

上面代码呢,我们给Vue原型添加了$notify对象,对象中编写了我们需要的通知方法,然后呢我们通过通知组件实例 notifyInstanse 去调用他的 showNotify 方法去打开通知,closeNotify 方法关闭通知。

打开通知时,第一个参数是通知内容,第二个就是消息类类型,这里就直接通过函数名 包装 了一层,还有延时参数,以及对loading的特殊处理,因为 javascript 没有函数重载的语法,不过我们可以通过判断参数类型分别进行处理,以 模拟函数重载 的场景。

下一步呢,我们只需在组件中实现 showNotifycloseNotify 就完事了。

index.js 的全部代码如下:

import Notify from './Notify.vue'

// 单实例
let notifyInstanse = null;

const NotifyPlugin = {
    install(Vue) {
        if (!notifyInstanse) {
            // Vue.extend() 方法创建了一个名为 NotifyComponent 的组件构造器。
            // 传入的参数是一个名为 Notify 的 Vue 组件。这个组件定义了通知组件的模板、样式和行为。
            // 只不过是组合了一下组件创建。
            const NotifyComponent = Vue.extend(Notify);
            // new NotifyComponent() 创建一个 notifyInstanse 对象,表示一个通知组件实例。
            notifyInstanse = new NotifyComponent();
            // 将通知组件挂载到DOM中
            const container = document.createElement("div");
            document.body.appendChild(container);
            notifyInstanse.$mount(container);
        }

        // 添加全局方法
        Vue.prototype.$notify = {
            success(message, duration) {
                notifyInstanse.showNotify(message, 'success', duration);
            },
            warning(message, duration) {
                notifyInstanse.showNotify(message, 'warning', duration);
            },
            info(message, duration) {
                notifyInstanse.showNotify(message, 'info', duration);
            },
            error(message, duration) {
                notifyInstanse.showNotify(message, 'error', duration);
            },
            loading(message, duration = 1000 * 60 * 60 * 24) {
                if (arguments.length == 1) {
                    notifyInstanse.showNotify(message, 'loading', 1000 * 60 * 60 * 24);
                    return
                }
                if (typeof arguments[1] == 'string') {
                    notifyInstanse.showNotify(message, 'loading', 1000 * 60 * 60 * 24, arguments[1]);
                    return
                }
                if (typeof arguments[1] == 'number') {
                    if (typeof arguments[2] == 'string') {
                        notifyInstanse.showNotify(message, 'loading', duration, arguments[2]);
                    } else {
                        notifyInstanse.showNotify(message, 'loading', duration);
                    }
                }

            },
            bug(message, duration) {
                notifyInstanse.showNotify(message, 'bug', duration);
            },
            happy(message, duration) {
                notifyInstanse.showNotify(message, 'happy', duration);
            },
            free(message, duration) {
                notifyInstanse.showNotify(message, 'free', duration);
            },
            close() {
                notifyInstanse.closeNotify();
            }
        }
    }
}

export default NotifyPlugin

4.8 实现两个方法 🥛

下面就是在 Notify.vue 组件实现打开和关闭通知的逻辑,使用 setTimeout 定时器,需要注意几个细节:

1.在使用时,如果多次点击是会重置延时的,所以在代码中,我们应该首先判断 timer 变量是不是有定时器,如果有先把原来的定时器清除了,然后再根据具体的延时,重新设置定时器。

2.通知显示与隐藏,借助了translate和transition过度动画,性能更好,也很简单。

<script>
export default {
  name: "notify",
  data() {
    return {
      // 通知内容
      message: '',
      // 通知类型
      type: '',
      // 延时
      duration: 3000,
      // 计时器
      timer: null,
      // 图标映射
      iconObj: {
        "success": "z-chenggong",
        "warning": "z-jinggao",
        "info": "z-tongzhi",
        "error": "z-icon-test1",
        "bug": "z-bug",
        "loading": "z-jiazai3",
        "happy": "z-kaixin",
        "free": "z-yinliao2"
      },
      iconStyle: '',
    }
  },

  methods: {
    showNotify(message, type, duration) {
      this.type = type;
      this.message = message;
      this.duration = duration || 3000;
      if (arguments[3]) {
        this.iconStyle = arguments[3];
      }
      // 通过translate上下移动,结合transition过度动画
      this.$refs.znotify.style.transform = "translate(-50%,55px)";
      if (this.timer) {
        this.timer = clearTimeout(this.timer);
      }

      this.timer = setTimeout(() => {
        this.closeNotify();
      }, this.duration);
    },
    closeNotify() {
      if (this.timer) {
        this.timer = clearTimeout(this.timer);
      }
      this.$refs.znotify.style.transform = "translate(-50%,0)";
    }
  },
  computed: {
    iconClass() {
      if (this.type == 'loading') {
        if (this.iconStyle == 'icon1') {
          return `z-jiazai_shuang rotate-icon`;
        } else if (this.iconStyle == 'icon2') {
          return `z-jiazai2 rotate-icon`;
        } else if (this.iconStyle == 'icon3') {
          return `z-jiazai1 rotate-icon`;
        }
        return `${this.iconObj[this.type]} rotate-icon`;
      }
      return this.iconObj[this.type];
    }
  },
}
</script>

4.9 修改固定模板 🏜️

我们在js代码中,已经将消息和图标类名抽取出来了,现在需要把html替换为动态变量,代码如下:

<template>
  <div class="z-notify" ref="znotify">
    <i class="zfont" :class="iconClass"></i>
    <span>{{message}}</span>
  </div>
</template>

组件 Notify.vue 全部代码如下:

<template>
  <div class="z-notify" ref="znotify">
    <i class="zfont" :class="iconClass"></i>
    <span>{{message}}</span>
  </div>
</template>

<script>
export default {
  name: "notify",
  data() {
    return {
      // 通知内容
      message: '',
      // 通知类型
      type: '',
      // 延时
      duration: 3000,
      // 计时器
      timer: null,
      // 图标映射
      iconObj: {
        "success": "z-chenggong",
        "warning": "z-jinggao",
        "info": "z-tongzhi",
        "error": "z-icon-test1",
        "bug": "z-bug",
        "loading": "z-jiazai3",
        "happy": "z-kaixin",
        "free": "z-yinliao2"
      },
      iconStyle: '',
    }
  },

  methods: {
    showNotify(message, type, duration) {
      this.type = type;
      this.message = message;
      this.duration = duration || 3000;
      if (arguments[3]) {
        this.iconStyle = arguments[3];
      }
      // 通过translate上下移动,结合transition过度动画
      this.$refs.znotify.style.transform = "translate(-50%,55px)";
      if (this.timer) {
        this.timer = clearTimeout(this.timer);
      }

      this.timer = setTimeout(() => {
        this.closeNotify();
      }, this.duration);
    },
    closeNotify() {
      if (this.timer) {
        this.timer = clearTimeout(this.timer);
      }
      this.$refs.znotify.style.transform = "translate(-50%,0)";
    }
  },
  computed: {
    iconClass() {
      if (this.type == 'loading') {
        if (this.iconStyle == 'icon1') {
          return `z-jiazai_shuang rotate-icon`;
        } else if (this.iconStyle == 'icon2') {
          return `z-jiazai2 rotate-icon`;
        } else if (this.iconStyle == 'icon3') {
          return `z-jiazai1 rotate-icon`;
        }
        return `${this.iconObj[this.type]} rotate-icon`;
      }
      return this.iconObj[this.type];
    }
  },
}
</script>

<style lang="less">
// 引入字体图标
@import url("../fonts/iconfont.css");
.z-notify {
  // 固定定位并居中
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  // 默认隐藏
  top: -32px;
  height: 30px;
  max-width: 70%;
  line-height: 30px;
  text-align: center;
  background: #e8e8e8;
  padding: 0px 16px;
  border-radius: 30px;
  transition: transform 0.55s;
  display: flex;
  align-items: center;
  i {
    display: block;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    margin-left: -5px;
    &::before {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 15px;
      height: 15px;
    }
  }

  span {
    color: #213547;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    user-select: none;
    padding-left: 4px;
    font-size: 13px;
    vertical-align: middle;
  }

  // 字体图标大小表现不一,微调
  .z-jiazai_shuang {
    font-size: 17px;
  }

  .z-chenggong {
    font-size: 13px;
  }
  .z-icon-test1 {
    font-size: 15px;
  }
  .z-jinggao {
    font-size: 15px;
  }
  .z-tongzhi {
    font-size: 13px;
  }
  .z-bug {
    font-size: 14px;
  }
  .z-kaixin {
    font-size: 14px;
  }
  .z-yinliao2 {
    font-size: 15.5px;
  }
  .z-jiazai1 {
    font-size: 20px;
  }
  .z-jiazai3 {
    font-size: 15px;
  }
  .z-jiazai2 {
    font-size: 13px;
  }
}

// 加载时的字体图标动画
@keyframes rotate-icon {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(1turn);
  }
}

// 加载时的字体图标类名
.rotate-icon {
  animation: rotate-icon 0.85s linear infinite;
}
</style>

至此呢,通知组件就封装完成啦,是不是很有意思呢?

在这里插入图片描述

5. 测试组件 🛠️

组件封装完成了,现在来测试一下吧!在 App.vue 中写两个按钮,一个打开,一个取消,然后调用封装的方法,如下:

<template>
  <div id="app">
    <button @click="$notify.loading('长时间加载')">打开</button>
    <button @click="$notify.close()">关闭</button>
  </div>
</template>

效果如下:

在这里插入图片描述

在这里插入图片描述

6. 打包组件 📦

好嘞,下面呢,来说说怎么打包我们的组件。

6.1 编写打包命令 ⌨️

来到 package.json 文件,添加一个脚本。

在这里插入图片描述

"package": "vue-cli-service build --target lib ./src/components/notify/index.js --name zhouql-notify --dest zhouql-notify",
  • ./src/components/notify/index.js 指的是打包的入口文件,这里就是通知组件的入口文件。
  • –name 参数配置打包后的文件名。
  • –dest 参数配置打包完成后生成的文件夹名。

理解了上面的几个参数之后呢,就可以编写自己的打包命令,然后运行就可以了,很快就打包好了。

6.2 整理打包文件 📄

这里看一下我打包后的目录结构:

在这里插入图片描述

其实我们只需要一个css和一个js文件就可以了,可以看到有3个js文件,其中 zhouql-notify.common.js 只能用 commonjs 的语法,zhouql-notify.umd.js 兼容AMD和commonJS规范的同时,还兼容全局引用的方式,所以我们用 zhouql-notify.umd.js 就可以了,还有一个js文件 zhouql-notify.umd.min.js ,这其实就是压缩版本的,看自己需要,可以看到压缩版的比没压缩的大小小了一大半,我选择压缩版的,哈哈。

所以这里的文件只保留 zhouql-notify.umd.min.jszhouql-notify.css 即可,其他的我就先删除了。

在这里插入图片描述

6.3 生成 package.json 📁

为了发包,我们需要一个package.json记录包信息。

在当前目录进入命令行,执行命令

npm init -y

即可生成默认的 package.json 文件。

在这里插入图片描述

6.4 修改 package.json 📁

main:这是主入口,也就是我们刚刚保留的 zhouql-notify.umd.min.js,当然也可以修改文件名为 index.js ,然后配置为 index.js 这都没有要求的,看自己需要,随便造。

name:这就是使用命令安装时的包名,不允许重复。

viersion: 版本

description:描述

scripts:脚本,咱这个不需要,删除即可

keywords:关键字,有利于别人发现你的包

author:作者

license:开源协议

homepage: 主页面,就是自定义的一个介绍页面,非必要

下面是我已经发布的包的配置,大家可以参考一下:

{
    "name": "zhouql-notify",
    "version": "1.0.6",
    "description": "vue2全局函数式提示组件,一行代码一条通知",
    "main": "index.js",
    "homepage": "http://zhouql.vip/notify/",
    "keywords": [
        "vue",
        "vue2",
        "js",
        "html",
        "css",
        "全局",
        "提示",
        "消息",
        "函数式组件"
    ],
    "author": "prince-zhouql",
    "license": "ISC"
}

在这里插入图片描述

6.5 README.md文件 📃

添加 README.md 文件,注意必须是大小,之前用小写没有起作用。

在这里插入图片描述

7. 发布组件 🎉

7.1 账号注册 📱

发布前,首先要在 npm 注册一个账号

打开 www.npmjs.com , 选择 sign up 进入账户注册页面

根据提示填写注册信息,点击注册后,填写的邮箱会收到一个验证码,输入验证码后即可完成注册。

完成注册后就可以看到 npm 个人主页了,到这里注册账户已经完成了。

7.2 检查源 ⛏️

使用命令检查npm下载源是不是官方的,有小伙伴可能用的淘宝镜像或者其他源,发包前需要切换到官方源,官方源是 https://registry.npmjs.org

npm config get registry

如果不是,使用下面命令切换到官方源

npm config set registry https://registry.npmjs.org

7.3 添加用户 🧑‍🎄

第一次发布用以下 (填写你注册的npm账号的username,password,email) 。
否则用 npm login 即可。

npm adduser

使用以下命令查看当前登录的npm用户。

npm whoami

7.4 推送 ⏏️

一定要把邮箱给认证了,否则publish会报错,切换到要发布包的入口,然后执行命令:

本文就是外层文件夹下执行。

在这里插入图片描述

npm publish

稍等片刻就可在 package里面看到自己的的npm包了。

7.5 更新版本 ✅

如果代码有更新,publish的时候需要更改版本号的,否则也提交不上。

方式两种如下:

  1. 直接改package.json

  2. npm指令操作package.json
    npm version patch //补丁版本,最后一位数加1
    npm version minor //增加了新功能 中间的数字加1
    npm version major //大改动,不向下兼容 第一位数字加1

7.6 删除包 ❗

执行下面命令删除自己发布的包,也可以在npm官网页面删除。

npm unpublish [packagename]--force

在这里插入图片描述

8. 安装自己编写的组件 😀

好了,到这里了,假设你已经上传了自己的包到npm,打开网站开到包的主页,这里以我的为例子。

在这里插入图片描述

可以看到右侧的安装命令,以及readme使用说明。

然后我们可以新建一个空的vue项目,然后使用以下指令安装库。

npm i zhouql-notify

安装成功后,打开 package.json 可以看到已经安装成功了。

在这里插入图片描述

然后根据 readme文件,引入组件,css文件,使用Vue.use()注册即可。

import Vue from 'vue'
import App from './App.vue'

// 引入组件
import Notify from "zhouql-notify"
// 引入样式文件
import "zhouql-notify/notify.css"
// 使用组件
Vue.use(Notify)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

然后在App.vue组件的 mounted钩子函数中调用测试如下:

<template>
  <div id="app">
  </div>
</template>

<script>

export default {
  name: 'App',
  mounted() {
    // 测试
    this.$notify.loading("加载中,成功了!", "icon3");
  }
}
</script>

启动项目并在浏览器打开,可以发现成功啦!是不是很开心呢。

在这里插入图片描述

在这里插入图片描述

9. 总结 📄

好玩,哈哈,对于像通知这样常用的组件,如果没有合适的,自己封装发布才是正确的打开方式。

在这里插入图片描述

恭喜你,读完了本篇文章,能力 + 100 ,颜值 + 10,欢迎下次再来。👋 先别走,如果觉得文章写的不错,还请点赞,收藏,关注帅气的博主啊,手动狗头,我会继续努力,原创不易,你的支持就是小周的动力 ☃️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/656930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

B047-cms02-高级查询 删除 添加 修改

目录 高级查询页面准备下拉框显示文章类型ArticleController用jstl和el表达式取值展示 高级查询参数ArticleQuery 高级查询页面发送请求导入jquery.jdirk.js在jquery下引用绑定按钮发送请求高级查询sql 绑定删除事件绑定事件拿到标签id值准备模态框来自xmind弹出删除模态框绑定…

matlab不显示子图刻度并调整子图间距

matlab中在使用subplot函数画图时&#xff0c;尤其是做emd分解查看IMF时&#xff0c; 正常画图的代码及结果如下&#xff1a; figure for i 1:size(imf_norm,1)subplot(7,1,i)plot(imf_norm(i,:))ylabel(IMFstring(i)) end其中imf_norm为分解得到的imfs 效果图&#xff1a; …

python里apply用法_Python apply函数的用法

Python编程语言Python 是一种面向对象、解释型计算机程序设计语言&#xff0c;由Guido van Rossum于1989年底发明&#xff0c;第一个公开发行版发行于1991年。Python语法简洁而清晰&#xff0c;具有丰富和强大的类库。它常被昵称为胶水语言&#xff0c;它能够把用其他语言制作的…

HDL抽象等级 仿真模型 网表 delay speicfy与sdf

1.HDL 硬件描述语言 抽象分级 HDL这里主要说verilog 在描述硬件电路时分为三个抽象级别 行为级模型&#xff1a;主要用于test bench&#xff0c;着重系统行为和算法&#xff0c;不在于电路实现&#xff0c;不可综合&#xff08;常用描述有initial&#xff0c;fork/join&#…

【MYSQL】MYSQL应用环境,系统特征,储存引擎,应用框架和索引功能的详细讲解

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

DINO-DETR匈牙利匹配与加噪过程学习记录

今天再来回顾一下DINO中匈牙利匹配与损失函数部分&#xff0c;该部分大致与DETR相似&#xff0c;却又略有不同。 为了查看数据方便&#xff0c;博主将num_query改为20&#xff0c;max_select值也为20。 匈牙利匹配过程 首先是数据送入匈牙利匹配中进行标签匹配过程了。 获取…

qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in

兄弟们看看是不是这个错&#xff1a; QObject::moveToThread: Current thread (0xe5205f0) is not the objects thread (0xa14d0f0). Cannot move to target thread (0xe5205f0)qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/xxx/python3.…

Esp32+Blynk实现云端控制LED开灭

目录 环境配置依赖库安装blynk 基础设置 GPIO 点灯实验 环境配置 依赖库安装 参考 blynk 官方快速上手文档 如果要使用 blynk 提供的环境&#xff0c;我们就必须安装对应的库 选择基于 blynk 且适用于 ESP32 的库并安装到 arduino 上&#xff1a; blynk 基础设置 进入官网并且…

Question1:harbor登录成功,推送镜像失败

denied: requested access to the resource is denied 解决方案 查看用户的权限 Harbor 用户角色权限速查 系统级角色&#xff1a; Harbor 系统管理员&#xff1a;“Harbor 系统管理员”拥有最多的权限。除了上述权限外&#xff0c;“Harbor 系统管理员”还可以列出所有项目、…

一种令人拍案叫绝的 ChatGPT 攻击手段!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 最近看到一个非常巧妙的 ChatGPT 攻击手段&#xff0c;跟大家分享一下&#xff0c;也算是做个提醒。 不论你是否懂技术&#xff0c;我都建议你了解一下这种攻击手段&#xff0c;有备无患。…

Golang的trace性能分析

文章目录 一、trace概述二、trace的使用方式代码中trace采集通过pprof采集 三、trace分析细节trace的web界面trace中需要关注的关注GC的频率关注goroutine调度情况关注goroutine的数量理想情况 四、GC分析当前服务GC情况设置GOGC设置GOMEMLIMITGC阈值的讨论GC的特点 五、gorout…

【每日挠头算法题(8)】最后一个单词的长度|重新排列字符串

文章目录 一、最后一个单词的长度思路1&#xff1a;从后往前遍历具体代码如下&#xff1a; 思路2&#xff1a;具体代码如下&#xff1a; 二、重新排列字符串思路具体代码如下&#xff1a; 一、最后一个单词的长度 点我直达~ 思路1&#xff1a;从后往前遍历 从后往前遍历&…

Stable DiffusionAI绘画一键启动整合包

点击"仙网攻城狮”关注我们哦~ 不当想研发的渗透人不是好运维 让我们每天进步一点点 简介 搞了个Stable DiffusionAI绘画整合包&#xff0c;里面有二次元风格、3D风格、真人模型&#xff0c;需要的后台回复“AI绘画”即可获取下载链接,放几个用SD生成的图。 实战 1.下载好…

调用万维易源API实现图像性别转换

目录 1、作者介绍2、调用万维易源API2.1 API介绍2.2 API调用过程 3、代码实现3.1 实现步骤3.2 完整代码 4、问题与分析 1、作者介绍 梁随欣&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生 研究方向&#xff1a;模式识别与人工智能 电子邮箱&…

【Java技术专题】「入门到精通系列教程」深入探索Java特性中并发编程体系的原理和实战开发指南( 线程基础技术专题)

深入探索Java特性中并发编程体系的原理和实战开发指南 并发编程介绍什么是并发编程并发编程的好处是什么并发编程的挑战是什么并发编程模型有哪些如何学习并发编程本系列专题文章大全 实战原理计算的问题简单的方法&#xff1a;更快的CPU来遍历靠谱的方法&#xff1a;分而治之来…

Redis客户端 - RedisSerializer

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis客户端 - RedisSerializer | CoderMast编程桅杆https://www.codermast.com/database/redis/redistemplate-redis-serializer.html 前景回顾 在上一篇中&#xff0c;我们实现了一个简单的案例&#xff0c;操作一个 St…

【22AP20 解码处理器(Hi3536AV100)】

22AP20 解码处理器(Hi3536AV100) 一、产品简介 22AP20 是针对多路高清/超高清&#xff08;1080p/4M/5M/4K&#xff09;智能 NVR 产品应用开发的新一代专业高端 SoC 芯片。22AP20 集成了 ARM Cortex-A55 八核处理器和性能强大的图像分析工具处理器&#xff0c;支持多种智能算法…

webpack无损压缩本地静态资源图片image-minimizer-webpack-plugin

开发如果项目中引用了较多图片&#xff0c;那么图片体积会比较大&#xff0c;将来请求速度比较慢。 我们可以对图片进行压缩&#xff0c;减少图片体积。 一、image-minimizer-webpack-plugin介绍 Image-minimizer-webpack-plugin是一个用于优化和压缩图片的Webpack插件。它使…

Qt5.15.2安装Android开发环境。

文章目录 1.下载并安装JDK1.1.下载1.2.安装 2.修改sdk_definitions.json文件3.QtCreator的配置3.1.设置JDK、Android SDK的路径3.2.设置openssl 现在&#xff08;20230617&#xff09;利用QtCreator来配置android开发环境还是挺方便的。基本三步搞定&#xff08;不过你要先安装…

《分布式中间件技术实战:Java版》学习笔记(一):抢红包

数据库建表 (1)red_send_record 记录用户发送了若干总金额的若干个红包。 CREATE TABLE red_send_record (id int(0) NOT NULL AUTO_INCREMENT,user_id int(0) NOT NULL COMMENT 用户id,red_packet varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL…