Vue 组件 | 如何从零封装一个tabbar组件

如何从零封装一个 Vue 组件哩?

今天来封装一个 tabbar 组件,在 CSS 效果 | tab 选项卡 中讲了使用原生 JavaScript 进行开发的方法,采用的是面向过程的编程思想。今天来用 Vue 封装一个类似的 tabbar 组件。

这个 tabbar 效果在移动端很常见,下面是一些例子。

pdd
zfb
jianshu

组件封装是为了复用,换成大白话就是,同样的事情我不想做第二遍,节省出来的时间用来看动漫不香吗?

好的,那怎么偷懒呢,根据杠杆原理,想要后期偷懒,前期就要尽可能地多考虑到会出现的各种情况。

先分析上面的图,从中早找出他们的共性和特性。


放一起,对比

共性是一个 TabBar 组件包含若干 TabBarItem 组件,数目一般不超过 6 个不少于 2 个,每个 TabBarItem 中包含一个 icon 和一行 text。特性是每个 TabBarItem 包含的 icon 和 text 的具体值是不同的,可以使用插槽。瞎掰完毕。


不妨使用上图的 jianshu 作为测试,封装一下 TabBar 组件。
在开始莽代码前,准备一波。

前期准备: icon图准备,使用的是阿里巴巴矢量图标库,根据 jianshu 的 TabBar 截图来看需要准备 5*2 个 svg icon,这应该是美工的活,如果有美工的话。

准备的icon

灰色 icon 是默认展示的,红色 icon 是被点击激活后展示的。


思路分析:


组件示例

整个看到的是一个大组件,大组件里有并列的 item,即上图中黄框部分,而每个 item 又可以抽离成小组件。

大组件定义插槽,传入小组件。小组件定义插槽传入图标和文字。


下面进入激动人心的编码环节。

编码开始:
不妨先在 App.vue 中编写:




效果

主要进行的基础结构的编写,基础布局是 TabBar 固定到底部,TabBarItem 平均布局,文字居中。


不妨建个文件抽离主要逻辑components/tabbar/TabBar.vue





与之对应 App.vue 就精简很多





第一次抽离

好的我们完成了第一次组件抽离,将 App.vue 拆成了 App.vueTabBar.vue


下面进入激动人心的第二次抽离。
不妨将准备好的 icon 放到 assets/img/tabbar 文件夹下,对于 icon 的命名有两种,一种是灰色 icon 采用英文命名,红色 icon 在对应的英文命名的基础上添加 _active的后缀,便于区分。下面就将准备好的 icon 引入到 Tabbar.vue 文件中吧。





明显,现在 TabBar.vue 文件也有些臃肿,下面进行第二次抽离即对 TabBar 进行抽离。





不妨建个文件抽离主要逻辑 components/tabbar/TabBarItem.vue 并微调样式。





这时可以在 App.vue 中进行使用。





文件结构确立

是不是有点内味了?此时的效果图如下。


效果图

好嘞,第二次抽离结束,今天组件的大致文件结构就是现在的样子了,如果需要更加个性化的操作,可能还会对其进行抽离,今天就先这样。

现在我们有三个文件,其中 App.vue 已经成为了测试文件,用来检验我们的组件,现在的重点是处理 TabBar.vueTabBarItem.vue


先缓一缓,将精力暂时先集中到 TabBarItem.vue 文件上,它是来处理单个 item 的,从上面的效果图来看,每个 item 都长得一样,很明显不符合我们的需求,不够个性化,明显我要传值进来,这就需要在 TabBarItem.vue 中定义一些插槽。

看图可以发现需要搞两个插槽,不妨分别给它们起名: item-icon item-text。

// TabBarItem.vue

在测试文件 App.vue 里进行插值操作测试。


  
    
    
首页
关注
消息
我的

经过一番倒腾,组件的外在已经有那么回事了。


外在美

现在组件的外在搞好了,是一个纸片人的状态,下面让它动起来,响应我们的交互。
功能点1:点击变色。

这时就要用到我们准备的另外一组图片了,在 item 被点击时,我们给它换张图片,再搞一个插槽 item-icon-active 用来存储 item 被激活的 icon 。


有了新的插槽,我们就可以在 App.vue 中测试了,这里拿首页进行举例。



  
  
  
首页

此时的效果图如下:


我都要

嗯,连 icon 都成双成对的。。。

我们的使命是破坏它们,只能显示一个,要么是灰色 icon 要么是红色 icon 。

当 item 处于激活状态是要换成红色的 icon,同时文字也要变成红色。

也就是说现在的任务是条件展示,会涉及到 v-if 和动态绑定 class 的相关知识。






效果展示如下:


isActive

好的现在我们通过控制 isActive 的值来模拟 item 被激活的情况,通过 v-if 控制 icon 的切换,通过给文字动态添加类名并通过 CSS 来改变文字的颜色。

通过测试图可以发现一变全变,这个问题留在后面解决,肯定不能手动改 isActive 的值。


下面是第二个功能点:点击 item 跳转到对应的页面。

来人呀,上路由。

准备工作:编写各个组件,放到 views 文件夹中,下面是 Profile.vue 的示例代码。


下面是配置的路由表。

const routes = [
  {
    path: '',
    redirect: '/home'
  },
  {
    path: "/home",
    component: Home
  },
  {
    path: '/love',
    component: Love
  },
  {
    path: '/diamond',
    component: Diamond
  },
  {
    path: '/comment',
    component: Comment
  },
  {
    path: '/profile',
    component: Profile
  }
]

TabBarItem.vue 文件中去监听点击事件并进行调转功能的实现。

// 核心代码
this.$router.replace(this.path)
传值

App.vue 文件通过 path="/home" 将对应的跳转路径传给 TabBarItem.vue 通过监听组件的点击执行 itemClick() 跳转到对应的组件。

效果

第二个功能点实现。


目前功能点1还有一些问题,路由切换时,图片和文字没有改变,这是因为之前 isActive 是写死的,下面进行动态变化。

现在要解决的问题是如何知道当前哪个 item 处于活跃状态,知道之后我们就可以对 isActive 进行动态的赋值。这里要用到 this.$route

// TabBarItem.vue
computed: {
  isActive() {
    // return this.$route.path.indexOf(this.path) !== -1
    return this.$route.path.includes(this.path)
  }
}

这里使用 indexOf()includes 都是可以实现相应功能,但后者语义化更强。

收工

经过一番的倒腾,这个 TabBar 组件就封装好了。下面是一些边角料。


更加个性化的操作,活跃时字体的颜色可能并不是红色。我们可以动态设置。


动态传入颜色
非主流
更加复杂的场景

其实可以个性化的地方还有很多,如上图可能需要显示红点或者未读信息的数目等。比如整个大的背景色,TabBar 的位置可能在页面的上方区域。

本文是对 TabBar 组件的简单封装,具体哪些需要个性化可能需要考虑具体项目,个性化的地方也不是越多越好,暴露的接口越多,稳定性等方面可能会有一定程度的减低,维护成本也会增多,一句俗话:适合自己的才是最好的。

你可能感兴趣的:(Vue 组件 | 如何从零封装一个tabbar组件)