在说封装上传至npm之前,先了解一下,组件和插件的区别。
借鉴:https://blog.csdn.net/chengQunBin/article/details/82318861
组件封装
首先,要创建项目,封装vue的组件/插件
1.新建一个文件夹smile-test
2.命令行进入文件夹下
3.执行npm init会产生一个package.json文件
4.创建如下目录结构的空文件夹即可
下面我们看一下项目目录结构:
image.png
接下来,
1、在src/component文件夹下创建本例一个组件的文件夹,本例为smileTest2,并在smileTest2文件夹内创建组件文件:本例为smileTest2.vue
2、在该文件中写入要发布的组件内容
下图写一个最简单的组件
image.png
代码如下:
<template>
<div>
<h1 class="smile">
smile 的第一个组件
</h1>
</div>
</template>
<script>
export default {
name: 'smileTest2',
};
</script>
<style scoped>
.smile{
color: aqua
}
</style>
3、在index.js文件里导出组件
image.png
代码如下:
import SmileTest2 from './src/components/smileTest2/smileTest2.vue'
export { SmileTest2 }
这里要注意export和 export default的区别
https://www.cnblogs.com/sherrycat/p/11152994.html
4、配置发布文件啦!
若没有npm账号,可以先去npm官网https://www.npmjs.com/package/npm注册一下,需要在邮箱内激活才可发布,若没激活,执行npm publish发布会报错,到时候百度也能查到是不是这个原因
注意:上传至npm的组件名称(下图第一个标注name字段)要唯一,不能与npm现有的组件名冲突,会报错
如下:
image.png
5、在终端执行npm publish
上传成功之后,打开npm官网,登录成功后,点击头像-->packages即可看到本账号发布的组件,选择要下载的组件,单击进入详情,如下图:
image.png
点击右侧即可复制 下载使用
使用
1.在需要使用该组件的项目中下载组件包
2.引用组件包
在需要调用本组件的页面引入组件并使用,代码如下:
<template>
<div>
<SmileTest2 />
</div>
</template>
<script>
import { SmileTest2 } from 'smile-test2'
export default {
name: 'HelloWorld',
components:{ SmileTest2 },
data () {
return {
}
}
}
</script>
<style scoped>
</style>
组件封装上传至npm就完成啦!
image.png
插件封装
1.创建项目同组件封装,本例为封装两个弹窗插件,一个输入弹窗,一个提示弹窗
项目目录结构如下:
2.分别在confirm文件夹下写提示弹窗组件,在confirmInput文件夹下写输入弹窗
为了方便起见,本例就先写提示弹窗:在confirm文件夹下新建confirm.vue文件,和index.js文件
confirm.vue代码如下
<template>
<div v-if="show_flag">
<div class="alert-bg"></div>
<transition name="confirm-bounce">
<div class="alert-content-cxt" v-show="show_flag">
<div class="alert-content">
<div class="alert-text-content" v-html="confirm_text"></div>
<div class="alert-btn-operate">
<div v-if="type === 1" class="aler-sure-btnA" @click="confirm()">{{confirm_btn_text}}</div>
<div v-if="type === 2">
<div class="aler-del-btn" @click="cancel()" >{{cancel_btn_text}}</div>
<div class="aler-btn-verticalLine"></div>
<div class="aler-sure-btnB" @click="confirm()">{{confirm_btn_text}}</div>
</div>
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
export default {
data(){
return {
show_flag: 0,
confirm_text:'我是一个弹框',
confirm_btn_text:'确定',
cancel_btn_text:'取消',
type:1
}
},
created(){
},
methods:{
confirm(){
console.log('我是点击确认按钮')
},
cancel(){
console.log('我是点击确认按钮')
}
},
mounted(){
}
}
</script>
<style scoped>
/* 弹框和输入弹框的独立样式start*/
.alert-bg {
width: 100%;
height: 200%;
background-color: #000;
position: fixed;
top: 0;
left: 0;
opacity: 0.7;
z-index: 9999;
}
.alert-content-cxt {
text-align: center;
position: fixed;
z-index: 10000;
transform: translate(-50%, -50%) scale(1);
-webkit-transform: translate(-50%, -50%) scale(1);
-ms-transform: translate(-50%, -50%) scale(1);
-moz-transform: translate(-50%, -50%) scale(1);
top: 40%;
left: 50%;
animation: confirm-zoom 0.3s
}
.alert-head-bg {
width: 25%;
position: relative;
top: 15px;
}
.alert-content {
width: 280px;
min-height: 100px;
height: auto;
background-image: linear-gradient(-78deg, #FFF, #F9F9F9);
background-image: -moz-linear-gradient(-78deg, #FFF, #F9F9F9);
background-image: -webkit-linear-gradient(-78deg, #FFF, #F9F9F9);
border-radius: 5px;
}
.alert-text-content {
width: 260px;
height: 50px;
font-size: 15px;
line-height: 24px;
color: #242424;
text-align: center;
text-overflow: ellipsis;
padding: 16px 10px;
vertical-align: middle;
display: table-cell;
box-sizing: content-box;
}
/* 弹框和输入弹框的独立样式end */
/* 弹框和输入弹框的公用样式start */
.alert-btn-operate {
width: 100%;
height: 42px;
border-top: 1px solid #eee;
line-height: 41px;
text-align: center;
font-size: 16px;
}
.aler-sure-btnB,.aler-del-btn {
width: 48%;
}
.aler-sure-btnB {
float: right;
color: #eb5e3b;
}
.aler-sure-btnA {
width: 100%;
color: #eb5e3b;
}
.aler-del-btn {
float: left;
color: #9E9E9E;
}
.aler-btn-verticalLine {
width: 1px;
height: 41px;
float: left;
background-color: #eee;
}
/* 弹框和输入弹框的公用样式end */
.confirm-bounce-enter {
opacity: 0;
transform: translate3d(-50%, -50%, 0) scale(0.7);
}
.confirm-bounce-leave-active {
opacity: 0;
transform: translate3d(-50%, -50%, 0) scale(0.9);
}
</style>
index.js
import Vue from 'vue'
import confirm from'./confirm.vue'
const ConfirmConstructor = Vue.extend(confirm);
let instance;
export default{
ConfirmOpen(options = {}){
if (!instance) {
instance = new ConfirmConstructor().$mount(document.createElement('div'));
}
instance.show_flag = 1;
instance.type = options.type || 1;
instance.confirm_text = typeof options === 'string' ? options:(options.confirmText || '我是一个弹框');
instance.confirm_btn_text = options.rightText || '确定';
instance.cancel_btn_text = options.leftText || '取消';
document.body.appendChild(instance.$el);
instance.confirm = () => {
if(typeof options.confirmFn !== 'undefined' && typeof options.confirmFn === "function"){
options.confirmFn();
}else{
console.log('弹框确认按钮没有回调按钮');
}
document.body.removeChild(instance.$el);
}
instance.cancel = () => {
if(typeof options.cancelFn !== 'undefined' && typeof options.cancelFn === "function"){
options.cancelFn();
}else{
console.log('弹框取消按钮没有回调按钮');
}
document.body.removeChild(instance.$el);
}
},
ConfirmClose(){
if(instance){
instance.show_flag = 0;
}
}
};
3.插件定义好之后,在项目index.js文件里导出插件
代码如下:
'use strict'
import Confirm from './src/components/confirm/index' // 提示弹窗
import ConfirmInput from './src/components/confirmInput/index' // 输入弹窗
export default {
install: (Vue, Option) => {
Vue.$confirm = Vue.prototype.$confirm = Confirm.ConfirmOpen;
Vue.$confirmInput = Vue.prototype.$confirmInput = ConfirmInput.ConfirmOpen;
}
}
4.配置发布文件package.json
同组件配置文件
{
"name": "log56-dialog",
"description": "smile log56-dialog",
"version": "1.0.8",
"author": "smile",
"license": "MIT",
"private": false,
"main": "dist/index.js",
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"vue": "^2.5.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
}
5.执行npm pubish发布到npm
同样到npm个人packages中,复制指令在终端执行使用
使用
在终端执行完install语句之后,在main.js入口文件中引用
image.png
在需要调用窗口的方法中调用即可。
image.png
至此,插件可以正常使用啦!
image.png
最喜欢这种一运行就正常的页面啦!我在这块踩了好多坑,后期会挨个整理出来。
网友评论