使用VUE-CLI3方式开发组件
第一步:创建项目并编写myToast组件
开始编写一个 toast 组件
myToast.vue
创建一个目录myToast,先编写组件内容,具体代码如下:
<template>
<transition name="alert-fade">
<div id="toast"
v-show="visible"
class="dialog-tips dialog-center">
{{message}}
</div>
</transition>
</template>
<script>
export default {
data () {
return {
visible: false,
message: ''
}
}
}
</script>
<style lang="scss" scoped>
.alert-fade-enter-active,
.alert-fade-leave-active {
transition: opacity 0.3s;
}
.alert-fade-enter,
.alert-fade-leave-to {
opacity: 0;
}
.dialog-tips {
position: fixed;
z-index: 100;
min-width: 100px;
padding: 15px;
border-radius: 15px;
white-space: nowrap;
background-color: rgba(0,0,0,1);
box-shadow: 0px 8px 30px 0 rgba(0, 0, 0, 0.363);
text-align: center;
color: #fff;
font-size: 15px
}
.dialog-center {
top: 20%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
index.js
接着编写组件入口文件index.js
import myToast from './myToast.vue'
const toast = {}
toast.install = Vue => {
// 扩展 vue 插件
const ToastCon = Vue.extend(myToast)
const ins = new ToastCon()
// 挂载 dom
ins.$mount(document.createElement('div'))
// 添加到 body 后面
document.body.appendChild(ins.$el)
// 给 vue 原型添加 toast 方法
Vue.prototype.$toast = (msg, duration = 3000) => {
// 我们调用的时候 赋值 message
// 将 visible 设置为 true
// 默认 3s 之后 设置 为 false 关闭 toast
ins.message = msg
ins.visible = true
setTimeout(() => {
ins.visible = false
}, duration)
}
}
export default toast
在该组件中,需要先引入之前的组件文件,并编写插件需要的install方法,在方法中添加$toast方法到vue实例对象上,这样在所有vue实例中都可以调用了。
组件引入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import toast from './components/myToast'
Vue.use(toast)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
组件使用
打开views/Home.vue文件,引入全局组件
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<button v-on:click="greet">Greet</button>
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
methods: {
greet(){
this.$toast('my toast test!')
}
}
}
</script>
效果如下:
第二步:重构项目 for component build
创建一个项目,之后将 src 目录改成 examples 这样会导致项目跑不起来,为啥是因为 vue-cli3 内置配置了自动回去找 src 文件夹,然后再新建一个 packages 文件夹,这样就把目录准备好了,如图所示
下面解决项目跑不起来的问题,主要在 vue.config.js 配置项目的入口文件
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
// 修改 src 为 examples
pages: {
index: {
entry: "examples/main.js",
template: "public/index.html",
filename: "index.html"
}
},
// 组件样式内联
css: {
extract: false
},
// 扩展 webpack 配置,使 packages 加入编译
chainWebpack: config => {
config.resolve.alias
.set('@', resolve('examples'))
.set('~', resolve('packages'))
config.module
.rule('eslint')
.exclude.add(path.resolve('lib'))
.end()
.exclude.add(path.resolve('examples/docs'))
.end()
config.module
.rule('js')
.include
.add('/packages/')
.end()
.include.add(/examples/)
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
};
注意:这里可以不用把src改名,上面的配置也只需要css内联处理,如下:
// 组件样式内联
css: {
extract: false
}
第三步:配置 package.json
主要是配置包导出入口 main,还有打包成 lib
{
"name": "big-bear-toast",
"version": "0.1.0",
"main": "packages/myToast/index.js",
"scripts": {
"lib": "vue-cli-service build --target lib --name toast --dest lib packages/myToast/index.js",
"serve": "vue-cli-service serve --hot",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"node-sass": "^6.0.0",
"sass-loader": "^10.2.0",
"vue-template-compiler": "^2.6.11"
}
}
vue-cli-service build
Options:
--mode 指定环境模式 (default: production)
--dest 指定输出目录 (default: dist)
--modern 构建两个版本的 js 包:一个面向支持现代浏览器的原生 ES2015+ 包,以及一个针对其他旧浏览器的包。
--target 允许您以项目库或Web组件的形式在项目内部构建任何组件 app | lib | wc | wc-async (default: app) ???
--name lib或者web组件库的名称 (default: "name" in package.json or entry filename)
--no-clean 在构建项目之前不要删除输出目录(dist)
--report 生成report.html以帮助分析包内容
--report-json 生成report.json来帮助分析包内容
--watch 监听 - 当有改变时 自动重新打包~
第四步:在根目录创建packages
在根目录创建packages并把myToast移动到这里,然后把main.js中路径改下,如下
执行打包生成lib 接着把生成的包引入到main.js中,如下
第五步:注册npm账号
首先要登录npm官网进行注册
按照上边的要求输入的全名、用户名、邮箱、密码进行注册
输入完成后点击下边的注册就可以创建自己的npm账号成功
值得注意的地方是,如果你的 npm 镜像是 淘宝镜像或者其他的镜像,此时应该切换会 npm
第六步:npm 登录及发布
输入命令npm login
如下:
项目中 package.json 配置了 private: true要改为false或者删除该项目.
发布成功!
组件测试
安装发布的组件
注意:要新建一个工程,不能在原发布工程中install
第七步:完善插件说明文档
主要是修改README.md
,大概内容如下:
常见问题收集
接下来就是遇到的问题了,每个问题都包含报错信息,请善用ctrl + f
搜索,下文报错中涉及到自己包名的我都替换为了your-package
。
邮箱未验证
这个是注册后没有验证邮箱,登录自己邮箱找到对应的邮件确认就好了。注意别选错了,注册 npm 时会发给你两个邮件,我当时就是眼瞎没有看到第二个。如果验证邮件过期的话登录自己的 npm 主页重新发一个就好了。
没有权限发布
你的包和别人的包重名了,npm 里的包不允许重名,所以去 npm 搜一下,改个没人用的名字就可以了。
需要登录
后面已经注明了,输入npm adduser
重新登录就可以了,过程和npm login
一样,这个问题在你切换了 npm 源之后或登录过期后都有可能发生。
只有管理员才有权限发布
这个是你的源设置成第三方源的时候才有可能发生,比如设置了淘宝源就可能会导致该问题。只要把源改回默认的就可以了,如下:
包名过于类似
如果npm上已经有了不少和你的包名类似的包,就会出现这个问题,在package.json
中修改你的包名就可以了
无法发布到私有包
这个当你的包名为@your-name/your-package
时才会出现,原因是当包名以@your-name
开头时,npm publish
会默认发布为私有包,但是 npm 的私有包需要付费,所以需要添加如下参数进行发布: