第11集:从零开始实现一套PC端Vue的ui组件库(tab切换组件)
时间:2023-04-05 22:40:26
HTML5
第11集:从零开始实现(tab切换组件)本集定位:先说一下tab切换的意义吧,不管是手机还是PC,屏幕的大小都是有限的,人眼能看到的范围能看到的也是有限的,人们在看资料的时候不喜欢“跳转”的操作,或者我们想查看某个知识点,进入网站后,看了不需要的相关资料后,就是自然退出,继续寻找。而且有时候我们想要的一些知识点可能在网站的底部,但是人有浏览习惯,所以需要在第一眼看到的区域尽可能多的展示“关键词”和“关键信息”,tab正好解决了有限空间如何‘扩展’的问题。选项卡组件不同于其他组件,他至少需要两个组件才能完成功能,写三个组件用起来很烦人,只写一个组件,无论是语义还是写法,都太差劲了。参考element的设计,我们这次同样使用了双组件。写它和单个组件的区别在于它涉及到两个组件之间的通信。问题1:需求分析由两部分组成。上半部分是标题的显示,下半部分是根据选中状态显示内容。标题必须具有明确的激活状态。为了性能,内容展示不能像这种封装类型的组件使用v-if,不允许干扰用户的任何操作。例如,没有.stop修饰符。使用方法如下。我使用cc-tab作为包组件的父标签cc-tab-pane是每个显示内容的标签1号内容2号内容No.3内容预期效果:2:基本构建vue-cc-ui/src/components/Tab/index.jsimportTabfrom'./main/tab.vue'importTabPanefrom'./main/tab-pane.vue'Tab.install=function(Vue){Vue.component(Tab.name,Tab);Vue.component(TabPane.name,TabPane);};exportdefaultTabcontainercomponentvue-cc-ui/src/components/Tab/main/tab.vue//毕竟标签比较多,ul的语义李当然是最好的;//比如你有3个标题,就用3个div,但是用ul就需要4个li标签各有利弊。标签名//此处显示内容
vue-cc-ui/src/components/Tab/main/tab-pane.vue只负责展示和提供组件参数给容器
//展示的内容我们直接写在标签里,所以slot就够了
容器组件还需要接收参数label,也就是tab显示的标签名称(给用户看的)name即,点击时,单独设置label的id(开发用)还有一个原因,就是label可以重复,因为不是唯一标识,name不能重复。props:{label:{type:String,required:true},name:{type:String,required:true}},3:基本功能1.我们先做导航功能,让title显示在parent中container:://个人推荐代码规范//挂载和创建的钩子,放在底部//因为他不会经常变化,他只负责启动代码//他必须符合单一职责,不允许具体的逻辑判断//他启动的函数,如果是和初始化相关的,必须以'init开头'mounted(){this.initNav();}initNavinitNav(){//只负责处理每个itemthis.layer(item=>{letresult={label:item.label,name:item.name,icon:item.icon};//放入我们的导航数组this.navList.push(result);});},//原理和map,reduce等函数一样,//每一步都会吐给用户层(task){this.$slots.default.map(item=>task(item.组件实例));}说明:this.$slots:获取这个父容器中所有slot元素的对象,例如:v-slot:foo的内容会在vm.$slots.foo中找到,默认属性包括所有没有包含的节点在命名插槽中,或v-slot:default的内容。上面循环this.$slots.default得到的每一项都是'节点元素',为什么用''标记,因为这个节点是vue处理的,不是传统意义上的节点;componentOptions:顾名思义,组件的一些配置项,比如监听器未接收到的事件,tag标签名,propsData,propsData包含了我们需要的名称和标签,但是需要componentOptions.propsData.name来取值。componentInstance:组件状态,它的body组件的this上面的参数可以直接获取props传入的值,比如componentInstance.name会获取传入的名字,为什么选在上面?因为他只要'.'就可以得到值。曾经,程序员的本性。上面我们得到了用户传入的子组件的配置摘要,我们可以循环显示
//对于这种内容的展示,写个label代码布局比较舒服//展示他的labelname{{item.label}} handClick,点击事件负责将用户的操作显示给parent。毕竟,我们已经绑定了v-model,所以给一个输入事件。Tab-click是用户接受的事件。handClick(e,name){this.$emit("输入",名称);this.$emit("tab-click",e);//这里需要使用宏任务来改变选中项,否则测试时会出现显示不正确的bugsetTimeout(()=>this.initSeleced(),0);},initSeleced是选择的特殊方法//一句话initSeleced(){//使用我们之前定义的循环函数//item是每个子组件,这些子组件的数据是映射的,所以可以修改//当子组件的值与被激活的名称相同时,组件的显示被激活this.层(项目=>(item.showItem=item.name==this.value));},subcomponent