我要造轮子系列-一个轮子的诞生过程

前言

程序员圈经常流行的一句话:“不要重复造轮子”。在计算机领域,我们将封装好的组件、库,叫做轮子。因为它可以拿来直接用,直接塞进我们的项目中,就能实现对应的功能。

有些同学会问,人家都已经做好了,你再来重新弄一遍,有什么意义?这不是在浪费时间吗。

殊不知,造轮子是一种学习方式,能快速进步,造得好,是自己超强能力的表现,同时能增加自己的知名度,有些人靠造轮子成了大V,有些人靠造轮子写书,有些靠造轮子被大公司挖人。

日常工作我们都是专注业务代码开发,常常做增删改查操作,技术也很快遇到瓶颈,因业务代码也有大量的工作,一些需求组件,插件就会在网上找然后直接拿来用,例如轮播、选项卡、拾色器、时间选择器等等,要开发这些组件一来要精力和时间,很多公司的项目时间是不允许的 ,二来自己开发的会有bug、用户体验不够好等等,所以还是需要时间打磨,和工作上要讲求开发效率背道而驰。笔者尝试着利用碎片时间来开发日常工作用组件、从对组件的需求分析、代码部署、编写组件、并发布到npm和github上,分享我造轮子的过程。从此不再做面向百度的编程。^_^

本系列第一个轮子是我们常用Tab选项卡。这个东西已经是老生常谈的组件,笔者想由最简单开始。为了简化开发,继续用vue编写

需求分析

  1. 选项卡点击切换滑动显示
  2. 事件模式(是点击模式,还是经过模式)
  3. 选项卡自定义颜色,宽高
  4. 选项卡导航超出显示范围滚动

屏幕录制2021-06-27 上午8.46.21.gif

直接上代码

这个组件难点在处理边界上,获取鼠标可视范围的坐标值就可以判断滚动。当然组件后续还可以增加功能 比如增加纵向滚动,或者各种动画显示 增加自动滑动等等

<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、轮子的目录结构

image.png

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网站见到自己轮子啦
image.png

添加到github

添加到GitHub网上也有很多教程,我在自己的ide上添加github账号,设置公钥,等操作,就可以上传代码到github上

image.png

最后

从需求分析、代码部署、编写组件、发布npm、再到发布github几个环节,一个完整的轮子就完成啦。以后就有自己的轮子库啦 O(∩_∩)O哈哈~

有兴趣同学可以下载我的代码

npm

npm i nigo-vue-tab
复制代码

github

git clone https://github.com/shinewen189/nigofortest.git
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享