vue-menu菜单 从开发到npm包发布

最近在开发vue项目,其中一些组件采用自研的方式开发,在这里对于一些通用性较强的组件进行一些总结,本文记录一下vue-menu菜单组件的开发过程和npm包发布过程。

一、组件的开发

1、需求分析

组件需要的功能:

(1)点击或者鼠标hover某一元素后弹出下拉菜单;

(2)下拉菜单项具备点击功能;

(3)下拉项可以置灰,点击无效;

(4)可以为下拉菜单添加自定义的类;

2、创建项目:

vue init webpack vue-menu

设置项目配置,完成后再src文件夹下创建vmenu文件夹,包含一个index.js文件和一包含main.vue的src文件夹。

构建项目目录如图:

其中main.vue为下拉菜单的源代码文件,用来组织菜单结构,index.js作为组件的入口文件。

2.1 main.vue文件

main.vue文件中以ul标签和li标签的形式展示用户传入的list数据,并绑定li的点击事件,具体代码实现如下

main.vue模板:

<template>
    <div id='v-menu-wrap-div' class='v-menu-wrap' :style='{left:rect.left +"px",top:rect.top + rect.height + "px"}' >
        <ul ref='v-menu-ul' class='vmenu-operate-ul' :class='ulClass'>
	    <li v-for='liItem in list' @click='clickLiBtn(liItem)' :class='[liItem.disabled ===true ? "disabled":"",liItem.class]'>
		<span v-if='liItem.icon' class='v-menu-span-icon operate-icon' :class='liItem.icon'></span>
		<span>{{liItem.text}}</span>
	    </li>
	</ul>
    </div>
</template>

main.vue的script标签:

<script>
	export default{
		name:'vMenu',
		methods:{
			clickLiBtn(li){
				if(li.disabled){    //如果有disabled属性,则返回
					return;
				}else if(li.clickFun){
					li.clickFun(li);
				}
			}
		},
		data: function(){
			return {
			}
		},

	}
</script>

修改样式:

<style >
	div.v-menu-wrap{
		position:absolute;
		z-index:9999;
	}
	ul.vmenu-operate-ul{
		list-style: none;
		color:black;
		float: left;
    	min-width: 160px;
   	 	padding: 5px 0;
   	 	margin: 2px 0 0;
    	font-size: 14px;
    	text-align: left;
    	background-color: #fff;
		box-shadow: 0 6px 12px rgba(0,0,0,.175);
		border: 1px solid rgba(0,0,0,.15);
			
	}
	ul.vmenu-operate-ul li{
		line-height:20px;
		display: list-item;
		padding:3px 20px;
		cursor:pointer;
	}
	ul.vmenu-operate-ul li:hover{
		color: #fff;
		background-color: #39ace5;
	}
	ul.vmenu-operate-ul li.disabled,ul.vmenu-operate-ul li.disabled:hover{
		background-color:white;
		cursor:default;
	}
	ul.vmenu-operate-ul li.disabled span,ul.vmenu-operate-ul li.disabled:hover span{
		color: rgb(167, 167, 167);
	}
</style>

2.2 index.js入口文件

入口文件需包含一个导出对象,对象有一个install方法,在使用Vue.use('xxx')时,会调用该install方法,方法的第一个参数为Vue实例:

import vMenu from './src/main';

vMenu.install = function(Vue){

};

export default vMenu;

补充实例方法:

import vMenu from './src/main';

vMenu.install = function(Vue){
    Vue.prototype.$menu = function(event,options){
        var rect = {};
        //设置menu的top,left位置
	['top','left'].forEach(function(property){
		var scroll = property === 'top' ? 'scrollTop' :'scrollLeft' ;
		rect[property] = event.currentTarget.getBoundingClientRect()[property] + document.body[scroll] + document.documentElement[scroll];
	});
	rect['left'] = rect['left'] + 160 > document.body.offsetWidth ? document.body.offsetWidth-160 : rect['left'];
	['height','width'].forEach(function(property){
	    rect[property] = event.currentTarget.getBoundingClientRect()[property];
	});
        //配置options
        if(options){
		options.rect = rect;
		options.ulClass = options.ulClass ? options.ulClass :'';
	}else{
		let node = document.querySelector('#v-menu-wrap-div');
		if(node && node.parentNode){
			node.parentNode.removeChild(node);
		};
		return ;
	}
        //扩展vue实例
	var vmenu = Vue.extend(vMenu);
	var componentMenu = new vmenu({
		data:options
	}).$mount();
        //获取vue菜单,如果已存在,则移除
	let node = document.querySelector('#v-menu-wrap-div');
	if(node){
		document.querySelector('body').removeChild(node);
	}
        //显示menu菜单
	Vue.nextTick(function(){
	       document.querySelector('body').appendChild(componentMenu.$el);
	});
        //当点击页面时,自动隐藏menu
	document.onclick = function(e){
		let node = document.querySelector('#v-menu-wrap-div');
	    if(node){
		document.querySelector('body').removeChild(node);
		document.onclick = null;
	    }
        };
    }
};

export default vMenu;

2.3 测试

<template>
  <div class="hello">
    <h3>{{ msg }}</h3>
    <span @click='showMenu'>点我下拉菜单</span>
  </div>
</template>

<script>
......
methods:{
    showMenu(event){
      this.$menu(event,{
        list:[{
          icon:'',
          text:'vue',
          clickFun:this.showAlert,
        },{
          icon:'',
          text:'javascript',
          clickFun:this.showAlert,
        },{
          icon:'',
          text:'html',
          disabled:true,
          clickFun:this.showAlert,
        },{
          icon:'',
          text:'css',
          disabled:false,
          clickFun:this.showAlert,
        }],

        ulClass:'menuclass'
      })
    },
    showAlert(item){
      alert(item.text)
    }
</script>

效果如下:

至此,组件开发工作完成。

github完整代码:

https://github.com/jianfeng418/vue-menu

二、npm包发布

1、 通过webpack-simple新建项目,

vue init webpack-simple vue-menu

通过webpack-simple创建一个简易的项目,用于对源代码进行压缩,方便上传,使用。

1.1 将vue-menu的源代码拷贝到src文件夹下:

 1.2 修改webpack.config.js:

注意:该例子中将文件输出到dist文件夹下,而项目的.gitignore文件默认把dist/文件夹忽略,因此,修改.gitignore文件,删除/dist/行:

1.3 npm run build

运行该命令,构建生产项目后,查看dist文件夹,产生两个文件

1.4 修改package.json文件

name:修改为唯一的名称,和现有npm库不能冲突。该名称即为npm包的名称,用户通过该名称下载组件使用。

private:改为false;

main:用户引用组件时,系统通过该字段去寻找文件,即用户实际引用的文件,这里改成构建后的压缩文件;

1.5 登录npm账户

npm login

如果没有npm账号,先去npm官网注册自己的用户账号;

输入用户名、密码、邮箱后,显示登录成功的信息;

可通过npm whoami 命令查看当前npm用户:

1.6 发布npm

通过npm publish命令发布自己的包;注意包的名称必须是现有npm库不存在的名称;否则会发布失败;

登录npm官网,登录自己账号可以看到已经发布的npm包;

1.7 验证

下载刚刚上传的包:

npm install vue-menu-jf -S 

在new Vue前引入vMenu,在项目中引用:

import vMenu from 'vue-menu-jf'

Vue.use(vMenu);

验证成功,完成。

1.8 npm包升级

在升级已经发布的npm包时,需要更改package.json中的version字段,同样使用npm publish 命令发布。

相关推荐
环境配置 Node 下载地址http://nodejs.cn/ 安装文件下有一个绿色的图片交node.exe 点击运行 输入node -v进行检测是否安装成功 使用vue-cli(脚手架)搭建项目 vue-cli是vue官方提供的用域搭建基于vue+webpack_es6项目的脚手架工具 在线文档:https://github.com/vuejs/vue-cli 操作: 1.npm install -g vue-cli:全局下载工具 2.vue init webpack 项目名:下载基于webpack模板项目 3.cd 项目名:进入项目目录 4.npm install :下载项目依赖的所有模块 5.npm run dev :运行项目 6.访问项目:localhost:8080 项目目录结构 src assets:存放照片、css、js css js img components:存放组件 lib:存放模拟数据 router:配置路由 store:存放vuex vuex的安装:cd x项目目录 cnpm install vuex --save views:存放所有单页面 配置访问端口号: 根目录下有一个config文件夹,看名字就知道与配置有关,打开config目录下的index.js dev: { env: require('./dev.env'), port: 8092, autoOpenBrowser: true, assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {}, } 项目目录下:https://blog.csdn.net/weixin_39378691/article/details/83784403 1.安装elementUI:cd进入项目根目录,npm i element-ui -S 2.引入elementUI组件(main.js文件中) import Element from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(Element, { size: 'small' }) 项目目录下:https://blog.csdn.net/weixin_41432849/article/details/81988058 1.安装jquery:cd进入项目根目录, npm install jquery --save 2.在项目 build 里的webpack.base.conf.js 里加载webpack文件,注意,要放在配置文件第一行; const webpack = require('webpack') 3.在module.exports的最后加入 , plugins:[ new webpack.ProvidePlugin({ $:"jquery", jQuery:"jquery", jquery:"jquery", "window.jQuery":"jquery" }) ]
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页