elementui源码学习之仿写一个el-tabs

本篇文章记录一下,仿写一个el-tabs组件,有助于大家更好理解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续空闲了会不断更新并仿写其他组件。源码在github上,大家可以拉下来,npm start运行跑起来,结合注释有助于更好的理解。github仓库地址如下:https://github.com/shuirongsh...
知识点复习 为了更好的阅读后续代码,我们需要再来复习一下知识
vue中的render函数书写jsx语法
vue中我们写组件页面,常常是结构、逻辑、样式分离,如:
// 这里写样式

如果大家熟悉react语法,就会发现,react中是把结构和逻辑书写在一块的(jsx)语法,其实vue中也是可以使用jsx语法的,不过要在render函数中去写。比如我们要使用render函数写一个红色字体的H3标签、背景色黄绿色。代码可以如下书写:
.box { background: yellowgreen; } .h3Class { color: red; }

效果图:
elementui源码学习之仿写一个el-tabs
文章图片

上述代码我们只需要记住,jsx语法中使用单大括号去表示变量使用。
再一个就是render函数中,如何给子组件传参数呢?也是使用单大括号搭配点点点...,因为单大括号才表示变量。如下代码:
render(h) { const sendParamsData = https://www.it610.com/article/{ // 准备参数 props: { name: this.name, age: this.age, home: this.home, }, }; return ({/* 传递参数 */} ); },

饿了么官方el-tabs组件就是使用了jsx语法进行编写的(因为jsx语法更加灵活),故:普通业务需求template够用了。灵活复杂需求,考虑使用jsx
this.$slots.default拿到组件标签内容中非具名插槽的部分
this.$slots.default这个api,大家平常使用的可能不是特别多。这个api可以顾名思义。$slots,插槽的意思(复数,可能有多个),default默认的意思。那就是默认插槽的意思。即this.$slots.default这个变量保存了所有不是命名插槽且不是作用域插槽的所有普通插槽内容。是个数组(如果有的话)。我们来看下面的代码简单使用便明了
// 父组件 // 子组件

打印的this组件实例图如下:
elementui源码学习之仿写一个el-tabs
文章图片

当然,这里我们写的是普通标签h3,这里也可以写组件标签,那么this.$slots.default存储的就是组件标签了,能拿到组件所有东西,就可以去进一步,加工存储,传递使用。结合官方el-tabs组件的使用,代码如下:
用户管理 配置管理 角色管理

我们发现,好像很相似。是的,官方就是通过this.$slots.default这个数组,拿到每一个el-tab-pane组件上的labelname以及其他的信息,然后传递到tab-nav组件上,于是乎,tab-nav组件,就会显示出一个又一个的选项卡信息了(供用户点击)
父组件v-model传参,子组件props中key为'value'接收,'input'事件更改
我们看官方使用案例中,也发现v-model绑定在组件el-tabs组件上。平常我们使用v-model一般都是绑定在输入框、下拉框、切换之类的表单控件组件上。只需要写一个v-model就可以了,不用做别的操作。不过v-model若绑定在普通自定义组件上,用于父子组件传递参数(双向数据绑定),就需要我们多写点代码了。我们来看一下案例:
// 父组件 // 子组件

效果图如下:
elementui源码学习之仿写一个el-tabs
文章图片

原因:
// 父组件v-model=age相当于

所以,子组件需要在props中使用value接收,同时使用this.$emit("input", xxx)触发
开始仿写 首先要搭建一个tabs结构
我们知道tabs就是选项卡切换的意思,整体可以分为三部分:选项卡部分内容区部分整个选项卡盒子部分,所以这里我们新建三个文件,去实现这个tabs组件。
  1. tabs.vue文件(整个选项卡盒子部分),用来作为整个选项卡切换的大容器的文件,在这个文件中去处理选项卡部分逻辑,以及内容区部分逻辑
  2. tabNav.vue文件(选项卡部分)
  3. tabContent.vue文件(内容区部分)
图示如下:
elementui源码学习之仿写一个el-tabs
文章图片

当然这里笔者已经封装好了,先来看看如何使用,以及效果图,然后再看看封装的代码呗
使用封装好的组件

效果图
elementui源码学习之仿写一个el-tabs
文章图片

tabs.vue组件(相当于数据中转站)

tabNav.vue组件(接收tabs.vue的数据进行v-for动态渲染)
.my-tab-nav-item-box { width: 100%; border-bottom: 1px solid #e9e9e9; .my-tab-nav-item { // 转换成行内盒子,每一项都水平排列 display: inline-block; // 垂直居中 height: 40px; line-height: 40px; // 字体样式位置设置一下 font-size: 14px; font-weight: 500; color: #303133; margin: 0 12px; cursor: pointer; } // 非禁用时鼠标悬浮样式,注意这里not的使用 .my-tab-nav-item:not(.isForbiddenItem):hover { color: #409eff; } // 高亮项样式 .highLight { color: #409eff; border-bottom: 1px solid #409eff; } // 禁用项样式 .isForbiddenItem { cursor: not-allowed; color: #aaa; } }

myTabContent.vue组件(搭配v-show条件对比只渲染一个)
.my-tab-content-item { padding: 12px; }

总结 对于tabs切换效果,可以自己写,比如使用动态组件方式去写(笔者也写过动态组件的文章链接:https://juejin.cn/post/695769... ),或者自己封装一个tabs组件。
不过本文只是仿照饿了么官方封装的一个简单的组件(某些地方的写法也可能和官方不太一样,不过思路是相通的)。再一个官方封装组件的时候,需要考虑到非常多的情况(可能某些情况很少用到),本文只是仿写并实现常用的效果。实际开发中,组件的封装的程度,需要根据项目的需求情况,进行考量。不可过度封装,也不能不封装。毕竟组件复用的确能够提升开发效率。
【elementui源码学习之仿写一个el-tabs】如果本篇文章能够帮助您更好的理解el-tabs的流程原理、数据传递方式,万分感谢给咱的github仓库star一下哦。毕竟elementui源码学习之仿写xxx是一个系列文章,您的start是咱创作的动力哦^_^

    推荐阅读