现在以插件名为 vue-drag-infinite为例,具体内容可通过以下方式进行下载
github查看源代码
npm install --save vue-drag-infinite
第一步初始化一个项目
封装vue的插件用webpack-simple很合适,使用命令:vue init webpack-simple vue-gitment 进行项目初始化,项目结构如下图所示:
初始化项目结构
1 首先打开清除掉无用的文件 具体清除内容为:
1.src下的所有文件
2.根目录下的 index.html 文件
2 修改根目录下的 package.json 里的内容
{
"name": "vue-drag-infinite",// 插件名称 再初始化项目的时候 可以设置 也可以在这里进行修改
"description": "A Vue.js project",//插件描述
"version": "1.1.2",//版本号 每次向npm上 publish的时候要修改一下 自增的形式
"author": "zhaosq <615683167@qq.com>",
"license": "MIT",//许可证
"private": false,//默认是true 私人的 需要改为false
"main":"dist/vue-drag-infinite.js",//这个超级重要 决定了你 import xxx from “vue-drag-infinite” 它默认就会去找 dist下的vue-drag-infinite 文件
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
"babel-core": "^6.26.0", // 依赖包名称 以及对应的版本号
........ 此处依赖吧不做解释
}
}
3.修改根目录下方的 webpack.config.js文件内容
var path = require('path')
var webpack = require('webpack')// commonjs 的形式引入webpack
module.exports = {
// entry: './src/main.js',
entry: './src/lib/index.js',//文件入口
output: {//文件出口配置
path: path.join(__dirname, './dist'),// 出口路径
publicPath: '/dist/',//build打包路径
filename: 'vue-drag-infinite.js',//打包后文件名称 设置为与插件名称一致
libraryTarget:'umd',//libraryTarget会生成不同umd的代码,可以只是commonjs标准的,也可以是指amd标准的,也可以只是通过script标签引入的。
library:'VueDragInfinite',//library指定的就是你使用require时的模块名,这里便是require("VueDragInfinite")
umdNamedDefine:true//会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define。
},
module: {.....},//对应 vue文件 js文件 css文件 url文件 sass文件 style行内样式 进行解析
devtool: '#eval-source-map',//相关选项有几种 不再过多解释,现在要做的是在打包后不再生成.map结尾的文件 将值设为 false
}
4.进行插件内容的编写 根据vue官网要求 需要使用 install
先在 src文件下创建 lib文件夹 在lib文件夹下创建一个 index.js 和一个 vue-drag-infinite.vue文件
index.js文件内容如下
import vueDragInfinite from './vue-drag-infinite.vue'
const dragInfinite = {
install(Vue, options) {
Vue.component(vueDragInfinite.name, vueDragInfinite) // vuePayKeyboard.name 组件的name属性
// 类似通过 this.$xxx 方式调用插件的 其实只是挂载到原型上而已
// Vue.prototype.$xxx // 最终可以在任何地方通过 this.$xxx 调用
// 虽然没有明确规定用$开头 但是大家都默认遵守这个规定
}
}
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(dragInfinite);
}
export default dragInfinite;
vue-drag-infinite.vue文件内容如下
<template>
<div class="contain" ref="dragContain">
<div class="control" v-drag="contain">
<div style="line-height:30px;background:#409EFF;cursor:move;color:#fff;text-indent:15px;">
控制面板
</div>
<div style="padding:7px;" @mousedown="mouseDown($event,false)">
<el-form ref="form" size="mini" label-width="70px">
<el-form-item label="模板名称">
<el-input v-model="name"></el-input>
</el-form-item>
<el-row v-if="json.length">
<el-form-item>
<el-button type="primary" @click="onSave">保存</el-button>
</el-form-item>
<el-form-item label="宽度">
<el-input v-model.lazy="json[divindex].style.width"></el-input>
</el-form-item>
<el-form-item label="高度">
<el-input v-model.lazy="json[divindex].style.height"></el-input>
</el-form-item>
<el-form-item label="字体大小">
<el-select v-model.lazy="json[divindex].style.fontSize" placeholder="请选择字体大小">
<el-option label="12px" value="12px"></el-option>
<el-option label="14px" value="14px"></el-option>
<el-option label="16px" value="16px"></el-option>
<el-option label="18px" value="18px"></el-option>
</el-select>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="背景颜色">
<el-color-picker v-model.lazy="json[divindex].style.backgroundColor" show-alpha></el-color-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="文字颜色">
<el-color-picker v-model.lazy="json[divindex].style.color"></el-color-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="文字内容">
<el-input type="textarea" v-model="json[divindex].text"></el-input>
</el-form-item>
</el-row>
<el-row>
<el-button type="primary" size="mini" @click="addDive()">新增div</el-button>
</el-row>
</el-form>
</div>
</div>
<div v-drag="contain" class="drag" :class="{active:index == divindex}" v-if="json.length" v-for="(item,index) in json" @click="moveDiv(index,$event)" :style="item.style">
{{item.text}}
<i class="el-icon-menu sacle" v-if="index == divindex" @click="sacle($event)" @mousedown="mouseDown($event,true)" unselectable="on"></i>
<el-button type="danger" class="del" @click="del(index,$event)" v-if="index == divindex" icon="el-icon-delete" circle></el-button>
</div>
<div v-if="!json.length">暂时没有内容哦!!期待您的编辑</div>
</div>
</template>
<script >
export default {
name:'vue-drag-infinite', // 此处name名称 在index.js 文件中有引用 所以最好跟插件名称一致,避免chux
props: {
json: {
type: Array,
default: []
},
name: {
type: String,
default: '小清新'
},
},
data(){
return {
//外层容器的宽高 数值不带px单位
contain:{
xx:500,
yy:500
},
//存放拉伸放大时的 div的原始宽高 带px单位
movejson:{
moveWidth:'',
moveHeight:''
},
divindex:0,//当前选中div的序号 默认为0
}
},
mounted(){
this.contain.xx = this.$refs.dragContain.offsetWidth;
this.contain.yy = this.$refs.dragContain.offsetHeight;
},
methods:{
// 字符串转json对象
toJson(str){
let _str =eval('(' + str + ')');
return _str;
},
//外层div点击选择事件 绑定右上角设置面板
moveDiv(index,e){
let jsonNew = this.toJson('{"'+e.target.style.cssText.replace(/\; +/g, "\",\"").replace(/\: +/g, "\":\"").replace(/\;+/g, "").replace(/-\w/g, function ($) {return $.slice(1).toUpperCase();})+'"}');
//当前选中div的序号
this.divindex = index;
// 设置div框的 各种属性
for (let em in jsonNew) {
this.json[index].style[em]= jsonNew[em];
}
this.json[index].text= e.target.innerText;
},
//添加一个div块 默认的
addDive(){
let newJson = {
style:{
width:"80px",
height:"50px",
fontSize:"14px",
color:"#ffffff",
backgroundColor:"#333333"
},
text:'新的div'
};
this.json.push(newJson);
},
//删除当前div
del(i,e){
this.json.splice(i, 1);
if(i == this.json.length){
this.divindex = 0;
}
e.stopPropagation();
},
onSave(){
let data = this.json;
this.$emit('save',data)
},
//div上拉伸的阻止冒泡事件
sacle(e){
e.stopPropagation();
},
//div上拉伸的 放大 缩小div宽高
mouseDown(e,type){
if(type){
let that = this;
let oldX = e.pageX,oldY = e.pageY;
that.movejson.moveWidth = that.json[that.divindex].style.width;
that.movejson.moveHeight = that.json[that.divindex].style.height;
document.onmousemove = function (e){
let newX = e.pageX - oldX;
let newY = e.pageY - oldY;
that.json[that.divindex].style.width = ((newX+ parseInt(that.movejson.moveWidth))>=80?(newX+ parseInt(that.movejson.moveWidth)):'80')+'px';
that.json[that.divindex].style.height = ((newY+ parseInt(that.movejson.moveHeight))>=50?(newY+ parseInt(that.movejson.moveHeight)):'50')+'px';
}
document.onmouseup = function(){
document.onmousemove = document.onmouseup = null;
}
}
e.stopPropagation();
}
},
computed: {
},
directives:{
drag:{
bind: function (el, binding, vnode) {
el.onmousedown = function(e){
var disx = e.clientX - el.offsetLeft;
var disy = e.clientY - el.offsetTop;
document.onmousemove = function (e){
let left = e.clientX - disx;
let top = e.clientY - disy;
if(left<0){
left = 0;
}
if(top<0){
top = 0;
}
if(left>binding.value.xx-el.offsetWidth){
left = binding.value.xx-el.offsetWidth;
}
if(top>binding.value.yy-el.offsetHeight){
top = binding.value.yy-el.offsetHeight;
}
el.style.left = left+'px';
el.style.top = top+'px';
}
document.onmouseup = function(){
document.onmousemove = document.onmouseup = null;
}
}
},
}
}
}
</script>
<style lang='scss' scoped>
ul,li{margin:0px;list-style:none;padding:0px;}
.contain{height: 700px;background:#ddd; position: relative;user-select:none;}
.el-form-item--mini.el-form-item{
margin-bottom:7px;
}
.drag{
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
cursor:move;
background-color: red;
border:1px solid #FFF;
line-height:1.7;
box-sizing:border-box;
color:#fff;
overflow: hidden;
padding:5px;
.sacle{
position:absolute;
right:0px;
bottom:0px;
background-color:#909399;
cursor: se-resize;
font-size:15px;
}
.del{
position:absolute;
top:0px;
right:0px;
padding:5px;
box-shadow:0px 0px 10px rgba(255, 255, 255,0.5);
}
}
.drag.active{
border-radius:5px;
border:1px solid #85ce61;
box-shadow:0px 0px 20px rgba(0,0,0,0.5);
}
.control{
width:250px;
border-radius:5px;
overflow:hidden;
background-color:#B3C0D1;
position:absolute;
z-index:999;
right:20px;
top:15px;
}
</style>
5.插件打包 build
npm run build 在dist文件夹中会出现一个vue-drag-infinite.js 文件
由于在webpack.config.js 中设置了 devtool:false,所以不会出现.map文件
下一步 npm插件的发布
首先在npm官网上进行账号的注册,各位自行注册
下载git工具,在git官网上进行下载 主要有俩个命令
npm login //登陆
npm publish //上传
publish后的文件找不到dist文件夹
原因是我们的忽略文件默认忽略了 dist 文件
修改根目录下的 .gitignore 去掉忽略dist
关于出现各种npm publish 失败的情况 可以观看本人另一篇文章
点击这里
最后说一下 关于插件的使用描述 md文件的编写
详细语法可以自行百度
代码编写区域
# h1标签 ## h2标签 ###### h6 标签
以上内容 个人手打与总结,有错误的地方还望各位大神指出
网友评论