Vue3造轮子--Tab组件

414 阅读1分钟

前言: 前言:在写Tab组件时,写的笔记,记录一下学习过程~

Tab组件

一.Dialog需求分析

1. 参考一下别人的对话框

  • AntD
  • 还可以参考 Bulma、Element、iView、Vuetify等

2.需求

  • 点击 Tab 切换内容
  • 有一条横线在动

二.API设计

  • Tabs组件怎么使用
<Tabs>
    <Tabs title="导航1">内容1</Tabs>
    <Tabs title="导航2"><Component1 /></Tabs>
    <Tabs title="导航1"><Component1 x="hi" /></Tabs>
</Tabs><Tabs :data="[
     {title:'导航1', content: '内容1'},
     {title:'导航2', content: Component1},
     {title:'导航3', content: h(Component1, {x: 'hi'})},
]"/>

三.如何在运行时确认子组件的类型

1.检查 context.slots.default()数组

  • 学习 log 技巧,一层一层打印来分析结果,实用的编程技巧
console.log({...context});
console.log({...context.slots});
console.log({...context.slots.default});
console.log({...context.slots.default()});
console.log({...context.slots.default()[0]});
console.log({...context.slots.default()[0]});
console.log({ ...context.slots.default()[1]})

context.slots.default()数组.png

  • 打印defaults[0]
 setup(props, context) {
    const defaults = context.slots.default()
    console.log(defaults[0])
    return {
      defaults
    }
  }

观察default[0].png

  • 继续打印观察type
console.log(defaults[0].type === Tab)

观察defaults[0].type===Tab.png

若改成div观察

Tab改成div.png

  • 结论,通过观察可以发现,我们可以通过defaults[n].type === Tab来检测第n个是不是Tab的类型,同时在这里我们也深入的了解到了vue的原理,每一个Tab.vue它最终会导出一个对象,因为这个对象和defaults[n].type是全等的。

2.切换标签页

  • 用selected标记被选中的标签页
  • selected用index表示,不推荐
  • selected 用name表示,不方便
  • selected 用title表示,有漏洞

设计就是妥协的艺术

四.总结

1.用 JS 获取插槽内容

const defaults = context.slolts.default()

2.使用 Vue3 遇到的 bug

  • 确定自己代码的问题
  • 用一个例子复现 bug
  • 例子链接 和 bug 的复现步骤提交给 Vue 团队

3.钩子

  • onMounted /onUpdated / watchEffect

4.TypeScript泛型

const indicator = ref<HTMLDivElement>(null)

5.获取宽高和位置

const { width, left } = el.getBoundingClientRect()

const { width, left, top, bottom } = el.getBoundingClientRect(); 都可以获取

6.ES6 析构赋值的重命名语法

  • const { left: left1 } = x.getBoundingClientRect()
  • const { left: left2 } = y.getBoundingClientRect()

五.效果展示

QQ录屏20220723231829 00_00_00-00_00_30.gif

源码已放到Gitee托管,感兴趣的小伙伴可以访问 gitee.com/boheweb/min…