VUE3+VITE封装插件+发布到npm
VUE3+VITE封装插件+发布到npm
目录
一. 在 src 目录下创建一个 plugins 文件夹,用来存放插件
前言:
随着互联网内卷的今天,前端程序员的简历上写项目已经很普遍了,很难有竞争力,这里给大家分享一个如何自制组件库,并发布到 npm,面试官问你有什么实战项目,你说自己封装了一个 xxx-ui 组件库,那将会让面试官眼前一亮,本项目将详细介绍如何制作一个简单的按钮组件 + 弹窗组件,并发布到 npm
一. 在 src 目录下创建一个 plugins 文件夹,用来存放插件
二. 创建组件
因为组件库不仅仅有一个组件,所以我们创建两个
三. 编写这两个组件的代码
button.vue
<template>
<button class="btn"><span>
<!-- 自定义插槽 -->
<slot></slot>
</span></button>
</template>
<script setup>
</script>
<script>
export default {
//一定要写组件名
name: 'vue-button'
}
</script>
<style scoped>
.btn {
display: inline-block;
border-radius: 20px;
background-color: #f4511e;
border: none;
color: #ffff;
text-align: center;
font-size: 28px;
font-weight: 400;
padding: 18px;
width: 200px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
vertical-align: middle;
}
.btn span {
cursor: pointer;
display: inline-block;
position: relative;
transition: 0.5s;
}
.btn span::after {
content: ">";
position: absolute;
opacity: 0;
top: 0;
right: -20px;
transition: 0.5s;
}
.btn:hover span {
padding-right: 30px;
}
.btn:hover span::after {
opacity: 1;
right: 0;
}</style>
msg.vue
<template>
<div class="msg" ref="msg" :class="{ active: msgStatus }">
<div class="msg-warpper">
{{ text }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
//控制组件的显示
let msgStatus = ref(false)
let text = ref('')
const msgPlugin = function (msg,time=2000) {
text.value = msg
msgStatus.value = true
setTimeout(() => {
msgStatus.value = false
},time)
}
defineExpose({
//向外暴露方法
msgPlugin
})
</script>
<script>
export default {
name: 'vue-msg'
}
</script>
<style scoped>
.msg{
height: 22px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
width: 0;
min-height: 0;
text-align: center;
background-color: rgba(0, 0, 0, .5);
border-radius: 5px;
color: #fff;
transition: all 0.5s;
z-index: -1;
opacity: 0;
}
.msg.active{
width: 150px;
min-height: 25px;
opacity: 1;
z-index: 11;
}
</style>
在写这两个组件的时候,一定要记得对外暴露方法以及给组件命名
四. 编写入口文件
在 plugins 文件夹内创建 index.js 入口文件
//入口文件=>插件的入口=>统一管理文件
//动态引入文件
const requireComponent = import.meta.glob('./**/*.vue', { eager: true })
const install = (Vue) => {
if (install.installed) return
install.installed
Object.keys(requireComponent).forEach(fileName=>{
//第i个组件
const config = requireComponent[fileName]
//组件名 刚才写的组件名派上用场了
const conponentName = config.default.name
Vue.component(conponentName,config.default || config)
})
//这里也可以创建全局自定义指令 这里是创建了一个自动获取焦点的指令
Vue.directive('focus',{
mounted:function(el){
el.focus()
}
})
}
//环境检测
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
//对外暴露install方法
export default {
install
}
Vue3 的动态引入方法与 Vue2 的不同,因为 Vue3 的构建工具是 Vite,如果是 Vue2(webpack)可以使用这段代码
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import vueMsg from './plugins/index.js'
const Vue = createApp(App)
Vue.use(vueMsg)
Vue.mount('#app')
五. 引入本地测试
main.js 引入入口文件,使用 Vue.use() 方法挂载插件
官方对 Vue.use() 方法的说明:通过全局方法 Vue.use() 使用插件,Vue.use 会自动阻止多次注册相同插件,它需要在你调用 new Vue() 启动应用之前完成,Vue.use() 方法至少传入一个参数,该参数类型必须是 Object 或 Function,如果是 Object 那么这个 Object 需要定义一个 install 方法,如果是 Function 那么这个函数就被当做 install 方法。在 Vue.use() 执行时 install 会默认执行,当 install 执行时第一个参数就是 Vue,其他参数是 Vue.use() 执行时传入的其他参数。就是说使用它之后调用的是该组件的 install 方法。
<script setup>
import { nextTick, ref } from 'vue';
let msg = ref()
let text = ref('')
function submit() {
if (text.value!=='') {
nextTick(() => {
msg.value.msgPlugin('提交成功', 1000)
})
} else {
nextTick(() => {
msg.value.msgPlugin('输入不能为空', 1000)
})
}
}
</script>
<template>
<input v-model="text" type="text" v-focus>
<vue-button @click="submit">123</vue-button>
<vue-msg ref="msg"></vue-msg>
</template>
<style scoped></style>
在 App.vue 本地引入测试,通过 ref 获取组件对外暴露的方法,从而修改弹出的文字和显示的时间
import { fileURLToPath, URL } from 'node:url'
import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
build: {
outDir: "lib", //输出文件名称
lib: {
entry: path.resolve(__dirname, "./src/plugins/index.js"), //指定组件编译入口文件
name: "vue-msg",
fileName: "vue-msg",
}, //库编译模式配置
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ["vue"],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: "Vue",
},
},
}, // rollup打包配置
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
测试成功了!这时我们就可以进行打包了!
六. 配置 Vite
修改 vite.config.js 将 vite 设置为组件库打包模式
{
"name": "wwl-ui-msg", //包名字
"private": false, //是否私有
"version": "0.0.1", //版本号
"description": "一个简单的ui组件库", //描述
"main": "vue-msg.js", //入口文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": ["wwl","wwl-ui","WwlUi"],//在npm上可被搜索的关键字
"author": "",
"license": "ISC" //开源协议
}
在终端输入打包指令,如果出现如下文件夹,说明打包成功了
import './assets/main.css' import { createApp } from 'vue' import App from './App.vue' import wwlUi from 'wwl-ui-msg' import '../node_modules/wwl-ui-msg/style.css' createApp(App).use(wwlUi).mount('#app')
七. 配置插件的 package.json
首先我们在打包好的 lib 目录下,打开终端,然后执行
npm init -y
命令初始化 package.json
package.json
是用来配置我们上传到 npm 仓库的配置下面我们来配置一下
<script setup>
import { ref } from 'vue'
let text = ref('')
let msg = ref()
function submit() {
if (text.value !== '') {
msg.value.msgPlugin('提交成功',2000)
}else{
msg.value.msgPlugin('输入内容不能为空',2000)
}
}
</script>
<template>
<input v-model="text" v-focus type="text" >
<vue-button @click="submit">提交</vue-button>
<vue-msg ref="msg"></vue-msg>
</template>
<style scoped></style>
八. 上传到 npm
1. 登录到 npm,没有 npm 账号的话需要到官网注册
在终端输入 npm 登录指令
npm login
按回车键会自动弹出登录页面
我们输入发到邮箱的验证码 显示此页面就登录成功了
2. 终端输入 **npm publish**
就可以正式发布到 npm 仓库了
显示此结果说明已经发布成功了! 这时我们到 npm 官网就可以搜索到我们发布的插件了
九. 最终测试
我们创建一个新的 vue3 项目,然后用 npm 下载我们创建的插件
npm i wwl-ui-msg
我们用 main.js 引入插件和插件的 css
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import wwlUi from 'wwl-ui-msg'
import '../node_modules/wwl-ui-msg/style.css'
createApp(App).use(wwlUi).mount('#app')
在项目中使用
App.vue
<script setup>
import { ref } from 'vue'
let text = ref('')
let msg = ref()
function submit() {
if (text.value !== '') {
msg.value.msgPlugin('提交成功',2000)
}else{
msg.value.msgPlugin('输入内容不能为空',2000)
}
}
</script>
<template>
<input v-model="text" v-focus type="text" >
<vue-button @click="submit">提交</vue-button>
<vue-msg ref="msg"></vue-msg>
</template>
<style scoped></style>
终端输入 npm run dev 测试
npm run dev
我们可以看到,我们写的两个组件 vue-button 和 vue-msg 都可以正常使用了 !
教程到这里就结束了,希望对你们有帮助,如果还有不明白的地方欢迎在评论区讨论~