本篇文章记录一下,仿写一个el-tabs组件,有助于大家更好理解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续空闲了会不断更新并仿写其他组件。源码在github上,大家可以拉下来,npm start运行跑起来,结合注释有助于更好的理解。github仓库地址如下:https://github.com/shuirongsh...
知识点复习
为了更好的阅读后续代码,我们需要再来复习一下知识
vue中的render函数书写jsx语法
vue中我们写组件页面,常常是结构、逻辑、样式分离,如:
如果大家熟悉react语法,就会发现,react中是把结构和逻辑书写在一块的(jsx)语法,其实vue中也是可以使用jsx语法的,不过要在render函数中去写。比如我们要使用render函数写一个红色字体的H3标签、背景色黄绿色。代码可以如下书写:
效果图:
上述代码我们只需要记住,jsx语法中使用单大括号去表示变量使用。
再一个就是render函数中,如何给子组件传参数呢?也是使用单大括号搭配点点点...
,因为单大括号才表示变量。如下代码:
render(h) {
const sendParamsData = { // 准备参数
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组件实例图如下:
当然,这里我们写的是普通标签h3,这里也可以写组件标签,那么this.$slots.default
存储的就是组件标签了,能拿到组件所有东西,就可以去进一步,加工存储,传递使用。结合官方el-tabs组件的使用,代码如下:
用户管理
配置管理
角色管理
我们发现,好像很相似。是的,官方就是通过this.$slots.default
这个数组,拿到每一个el-tab-pane
组件上的label
、name
以及其他的信息,然后传递到tab-nav
组件上,于是乎,tab-nav
组件,就会显示出一个又一个的选项卡信息了(供用户点击)
父组件v-model传参,子组件props中key为'value'接收,'input'事件更改
我们看官方使用案例中,也发现v-model
绑定在组件el-tabs
组件上。平常我们使用v-model
一般都是绑定在输入框、下拉框、切换之类的表单控件组件上。只需要写一个v-model
就可以了,不用做别的操作。不过v-model
若绑定在普通自定义组件上,用于父子组件传递参数(双向数据绑定),就需要我们多写点代码了。我们来看一下案例:
// 父组件
// 子组件
孙悟空年龄是:{{ ageValue }}
效果图如下:
原因:
// 父组件v-model=age相当于
所以,子组件需要在props
中使用value
接收,同时使用this.$emit("input", xxx)
触发
开始仿写
首先要搭建一个tabs结构
我们知道tabs就是选项卡切换的意思,整体可以分为三部分:选项卡部分
、内容区部分
、整个选项卡盒子部分
,所以这里我们新建三个文件,去实现这个tabs组件。
tabs.vue
文件(整个选项卡盒子部分),用来作为整个选项卡切换的大容器的文件,在这个文件中去处理选项卡部分
逻辑,以及内容区部分
逻辑tabNav.vue
文件(选项卡部分)tabContent.vue
文件(内容区部分)
图示如下:
当然这里笔者已经封装好了,先来看看如何使用,以及效果图,然后再看看封装的代码呗
使用封装好的组件
孙悟空内容
猪八戒内容
沙和尚内容
唐僧内容
白龙马内容
武松内容
松江内容
林冲内容
吴用内容
效果图
tabs.vue组件(相当于数据中转站)
tabNav.vue组件(接收tabs.vue的数据进行v-for动态渲染)
{{ tabItem.label }}
myTabContent.vue组件(搭配v-show条件对比只渲染一个)
总结
对于tabs切换效果,可以自己写,比如使用动态组件方式去写(笔者也写过动态组件的文章链接:https://juejin.cn/post/695769... ),或者自己封装一个tabs组件。
不过本文只是仿照饿了么官方封装的一个简单的组件(某些地方的写法也可能和官方不太一样,不过思路是相通的)。再一个官方封装组件的时候,需要考虑到非常多的情况(可能某些情况很少用到),本文只是仿写并实现常用的效果。实际开发中,组件的封装的程度,需要根据项目的需求情况,进行考量。不可过度封装,也不能不封装。毕竟组件复用的确能够提升开发效率。
如果本篇文章能够帮助您更好的理解el-tabs的流程原理、数据传递方式,万分感谢给咱的github仓库star一下哦
。毕竟elementui源码学习之仿写xxx
是一个系列文章,您的start是咱创作的动力哦^_^