前言
程序员圈经常流行的一句话:“不要重复造轮子”。在计算机领域,我们将封装好的组件、库,叫做轮子。因为它可以拿来直接用,直接塞进我们的项目中,就能实现对应的功能。
有些同学会问,人家都已经做好了,你再来重新弄一遍,有什么意义?这不是在浪费时间吗。
殊不知,造轮子是一种学习方式,能快速进步,造得好,是自己超强能力的表现,同时能增加自己的知名度,有些人靠造轮子成了大V,有些人靠造轮子写书,有些靠造轮子被大公司挖人。
日常工作我们都是专注业务代码开发,常常做增删改查操作,技术也很快遇到瓶颈,因业务代码也有大量的工作,一些需求组件,插件就会在网上找然后直接拿来用,例如轮播、选项卡、拾色器、时间选择器等等,要开发这些组件一来要精力和时间,很多公司的项目时间是不允许的 ,二来自己开发的会有bug、用户体验不够好等等,所以还是需要时间打磨,和工作上要讲求开发效率背道而驰。笔者尝试着利用碎片时间来开发日常工作用组件、从对组件的需求分析、代码部署、编写组件、并发布到npm和github上,分享我造轮子的过程。从此不再做面向百度的编程。^_^
本系列第一个轮子是我们常用Tab选项卡。这个东西已经是老生常谈的组件,笔者想由最简单开始。为了简化开发,继续用vue编写
需求分析
- 选项卡点击切换滑动显示
- 事件模式(是点击模式,还是经过模式)
- 选项卡自定义颜色,宽高
- 选项卡导航超出显示范围滚动
直接上代码
这个组件难点在处理边界上,获取鼠标可视范围的坐标值就可以判断滚动。当然组件后续还可以增加功能 比如增加纵向滚动,或者各种动画显示 增加自动滑动等等
<template>
<div class="tab" :style="{width : tabWidth +'px',height:tabHeight +'px',lineHeight:tabHeight+'px' }">
<div class="tab-nav">
<div class="tab-nav-con"
:style="{transform : `translatex(-${navWidth}px)`,width :tabNavWidth }">
<a :class="[current===index?'current':'']"
:style="{backgroundColor:current === index ? themeColor :'' }"
v-for="(item,index) in content"
:key="item.id"
v-on:[getIsNavMode].stop.prevent="switchTab(index,$event)">{{item.title}}</a>
</div>
</div>
<div class="tab-con">
<div class="j-tab-con"
:style="{transform:`translatex(-${contentWidth}px)`,width:setTabContentWidth}">
<div class="tab-con-item"
:style="{backgroundColor:item.color,width : tabWidth +'px' }"
v-for="(item) in content"
:key="item.id">
{{item.content}}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'tab',
props: {
//传入选项卡内容和导航标题
content: Array,
//自定义选项卡宽度
tabWidth: {
type: String,
default: 500,
},
//自定义选项卡高度
tabHeight: {
type: String,
default: 500,
},
//自定义颜色
themeColor: {
type: String,
default: '#80b600'
},
//自定义事件模式
navMode: {
type: String,
default: 'click'
}
},
data() {
return {
current: 0, //当前索引值
navWidth: 0, //选项卡导航初始 x 轴值
contentWidth: 0,//选项卡内容初始 x 轴值
}
},
computed: {
//计算选项卡导航总宽度
tabNavWidth() {
return (80 * this.content.length) + 'px'
},
//计算选项卡内容总宽度
setTabContentWidth() {
return this.tabWidth * this.content.length + 'px'
},
//自定义事件模式 click| mouseover
getIsNavMode() {
return this.navMode === 'click' ? 'click' : 'mouseover'
}
},
methods: {
switchTab(index, ev) {
const {layerX, target} = ev
const tabWidth = Number(this.tabWidth)
// 判断坐标边界返回然后设置滚动
if (layerX > tabWidth - target.offsetWidth && layerX < tabWidth + target.offsetWidth) {
this.navWidth += target.offsetWidth * 2
} else if (layerX > 0 && layerX < target.offsetWidth) {
this.navWidth -= target.offsetWidth * 2
}
if (this.navWidth < 0) this.navWidth = 0
this.current = index
this.contentWidth = index * tabWidth
}
}
}
</script>
<style scoped>
.tab {
position: relative;
overflow: hidden;
margin: 0 auto 20px;
border: 1px solid #ddd;
}
.tab-nav {
height: 30px;
overflow: hidden;
background: #f5f5f5;
border-bottom: 1px solid #ddd;
}
.tab-nav a {
display: block;
float: left;
width: 80px;
height: 30px;
line-height: 30px;
text-align: center;
text-decoration: none;
color: #999;
cursor: pointer;
}
.tab-nav a.current {
color: #fff;
}
.tab-con {
transition-duration: 500ms;
transition-timing-function: ease-out;
position: relative;
overflow: hidden;
}
.tab-con-item {
float: left;
text-align: center;
}
.j-tab-con {
overflow: hidden;
transition-duration: 500ms;
transition-timing-function: ease-out;
cursor: grab;
}
.tab-nav-con {
overflow: hidden;
transition-duration: 500ms;
transition-timing-function: ease-out;
}
</style>
复制代码
调用选项卡组件
<Tab
:content="[{title :1,content: ''},{title: 2,content: ''},{title:3,content:''}]"
tab-width="500"
tab-height="300"
theme-color="#333"
nav-mode="mouserover"
></Tab>
复制代码
发布到npm流程
轮子造好了就发布到npm
1、轮子的目录结构
2、打开 package.json
文件填写轮子的版本信息及各种依赖包
{
"name": "nigo-vue-tab",
"version": "1.0.0",
"description": "选项卡轮子",
"author": "nigo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"vue": "^2.5.11"
},
"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",
"style-loader": "^0.23.1",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.12.0",
"webpack-dev-server": ">=3.4.1"
},
"license": "ISC"
}
复制代码
3、发布到npm,前提,得有个npm账号,没有就新注册一个账号
www.npmjs.com/signup
4、进入到项目的根目录下,运行 npm login
执行登录
一般情况下回提示你输入 你的用户名,密码和邮箱,若登录成功一般会显示:
$ npm login
复制代码
5、登录成功后,运行npm publish
$ npm publish
复制代码
6、发布成功后,浏览npm网站见到自己轮子啦
添加到github
添加到GitHub网上也有很多教程,我在自己的ide上添加github账号,设置公钥,等操作,就可以上传代码到github上
最后
从需求分析、代码部署、编写组件、发布npm、再到发布github几个环节,一个完整的轮子就完成啦。以后就有自己的轮子库啦 O(∩_∩)O哈哈~
有兴趣同学可以下载我的代码
npm
npm i nigo-vue-tab
复制代码
github
git clone https://github.com/shinewen189/nigofortest.git
复制代码