Tencent / tdesign-vue-next

A Vue3.x UI components lib for TDesign.
https://tdesign.tencent.com/vue-next
MIT License
1.46k stars 474 forks source link

🎉 Composition Api 重构计划 #58

Closed XieZongChen closed 2 years ago

XieZongChen commented 2 years ago

说明

  1. 使用 Composition Api 语法重构,文件类型依然使用 tsx
  2. 参与贡献请在此 issue 中评论领取的组件
  3. 重构时的思考,避免 optionsAPI 照搬 compositionAPI
  4. 重构前联系管理员先进行一轮组件的 review

开发规范

https://github.com/Tencent/tdesign-vue-next/wiki/TDesign--CompositionAPI-%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83

基础Hook:

组件

全局组件

基础

布局

导航

输入

数据展示

消息提醒

chaishi commented 2 years ago

后面会输出 TagInput,SelectInput,暂时先别做 输入框相关的组件:cascader, select, treeselect , datepicker, timepicker

XieZongChen commented 2 years ago

button

uyarn commented 2 years ago

@amadeus711 icon是在icon库中维护的 已经是用composition API的方式实现的了。

uyarn commented 2 years ago

loading

Rainer-Yu commented 2 years ago

领取 checkbox

Rainer-Yu commented 2 years ago

现在项目内没有lock文件, 不需要统一开发环境依赖版本吗?

PengYYYYY commented 2 years ago

现在项目内没有lock文件, 不需要统一开发环境依赖版本吗?

开发者的源和npm版本,node版本都会存在不一致的情况。lock可能会导致一些差异,或者一些版本未被更新的情况。 我们在ci流程会用固定的环境跑test,lint,build。

PengYYYYY commented 2 years ago

cascader

Rainer-Yu commented 2 years ago

compositionApi中 provide/inject 的 injectKey 是需要单列文件 还是统一有什么规则

PengYYYYY commented 2 years ago

compositionApi中 provide/inject 的 injectKey 是需要单列文件 还是统一有什么规则

目前没有统一规则,对这一块又什么想法嘛

Rainer-Yu commented 2 years ago

compositionApi中 provide/inject 的 injectKey 是需要单列文件 还是统一有什么规则

目前没有统一规则,对这一块又什么想法嘛

是不是可以与props定义一样由脚本生成, 可以在一部分组件重构后进行尝试 同时希望 开放仓库的 discussions 进行社区讨论

PengYYYYY commented 2 years ago

compositionApi中 provide/inject 的 injectKey 是需要单列文件 还是统一有什么规则

目前没有统一规则,对这一块又什么想法嘛

是不是可以与props定义一样由脚本生成, 可以在一部分组件重构后进行尝试 同时希望 开放仓库的 discussions 进行社区讨

已放开讨论

youuss commented 2 years ago

领取 pagination

qunbotop commented 2 years ago

领取 divider

higuaifan commented 2 years ago

领取 tag

higuaifan commented 2 years ago

有些公共方法会出现一些不兼容的情况, 例如emitEvent这个,老版本的写法是用vm: ComponentPublicInstance的, 如果迁移到composition api上的话,getCurrentInstance获取到的是ComponentInternalInstance类型, 原本的$props$emit都要改成propsemit。 类似于这种情况是在emitEvent后新起一个func保证兼容性以及方便后期统一替换,还是有别的方案呢?

以及类似于这类问题是放issue还是到开发指南的discussions上去。。

PengYYYYY commented 2 years ago

有些公共方法会出现一些不兼容的情况, 例如emitEvent这个,老版本的写法是用vm: ComponentPublicInstance的, 如果迁移到composition api上的话,getCurrentInstance获取到的是ComponentInternalInstance类型, 原本的$props$emit都要改成propsemit。 类似于这种情况是在emitEvent后新起一个func保证兼容性以及方便后期统一替换,还是有别的方案呢?

以及类似于这类问题是放issue还是到开发指南的discussions上去。。

关于迁移compositionAPI的差异问题,新起一个 discussions 。 关于emitEvent 以及其他公共 func 可以起一个新的 func 先保证兼容性

XieZongChen commented 2 years ago

如果大家有关于重构的想法和问题,可以到这里进行讨论 #84

gumingWu commented 2 years ago

领取input

simpleAndElegant commented 2 years ago

领取 comment

chaishi commented 2 years ago

Cascader / DatePicker / TimePicker / TreeSelect 等组件 Vue2 本身还需要继续建设,大家先不要重构

这些组件会单独抽出一个 SelectInput 统一控制输入框和下拉框逻辑

chaishi commented 2 years ago

有些公共方法会出现一些不兼容的情况, 例如emitEvent这个,老版本的写法是用vm: ComponentPublicInstance的, 如果迁移到composition api上的话,getCurrentInstance获取到的是ComponentInternalInstance类型, 原本的$props和$emit都要改成props和emit。 类似于这种情况是在emitEvent后新起一个func保证兼容性以及方便后期统一替换,还是有别的方案呢?

emitEvent 是 Vue2 特有的写法,为了支持 <checkbox @change="xxx"/><checkbox :onChange="xxx" 两种写法。Vue3 不需要 emitEvent

⚠️ 看到 emitEvent 的地方,Vue3 组件内部直接执行 this.onChange(xxx) 即可。 ⚠️

@higuaifan @pengYYYYY

chaishi commented 2 years ago

https://github.com/Tencent/tdesign-vue-next/pull/96

image

https://v3.cn.vuejs.org/guide/composition-api-introduction.html#setup-%E7%BB%84%E4%BB%B6%E9%80%89%E9%A1%B9

突然,在思考一个关于 composition api 问题:

从官网描述来看,CompisitionAPI 的出发点是为了在复杂的业务场景中可以更好的复用各类逻辑。setUp 函数也是因为逻辑复用而存在。

如果压根儿没有什么需要复用的逻辑,我们仅仅是把每个组件改成 setup 写法的目的是什么?

改成 setup 写法,代码真的更容易阅读了吗?(从 Comment 的实际代码来看,并没有深刻的感受。原先的拆分写法逻辑也是相对独立的,阅读上并没有障碍。)


看了下 Element Plus 某组件代码:https://github.com/element-plus/element-plus/blob/dev/packages/components/calendar/src/calendar.vue

这样的写法,把什么内容都放在 setup 里面的写法真的是更简洁了吗?代码真的有复用起来了吗

这样子把什么都写在 setup 里面,真的比以前的 options API 更合理吗 为什么我觉得 Element 这一波代码看起来还不如之前的 options API 变量、方法、计算属性 分开的写的方式呢


结尾,提一个问题:

为什么我们一定、必须、非得把每一个组件都改造成 Composition API ?(仅供讨论,欢迎大家发表意见)

仔细对比 Options API 和 Composition API 两种写法,真的是每一种情况下,每一个组件,每一个业务场景里面,Composition API 都更好吗?

https://github.com/element-plus/element-plus/blob/dev/packages/components/calendar/src/calendar.vue 大家在看这一波代码的时候,不觉得就是一个巨大的 setup 函数吗?有点强行 Composition API 的感觉


我们是否可以在必要的时候再使用 Composition API ?(通用逻辑再使用 useXXX 这种写法)

higuaifan commented 2 years ago

有些公共方法会出现一些不兼容的情况, 例如emitEvent这个,老版本的写法是用vm: ComponentPublicInstance的, 如果迁移到composition api上的话,getCurrentInstance获取到的是ComponentInternalInstance类型, 原本的$props和$emit都要改成props和emit。 类似于这种情况是在emitEvent后新起一个func保证兼容性以及方便后期统一替换,还是有别的方案呢?

emitEvent 是 Vue2 特有的写法,为了支持 <checkbox @change="xxx"/><checkbox :onChange="xxx" 两种写法。Vue3 不需要 emitEvent

⚠️ 看到 emitEvent 的地方,Vue3 组件内部直接执行 this.onChange(xxx) 即可。 ⚠️

@higuaifan @pengYYYYY

👌疏忽了对函数本身作用的思考,感谢提醒

higuaifan commented 2 years ago

个人觉得像 Element Pluscalendar.vue这样全都丢在一个setup的写法可读性和使用Options API差不多差,要阅读一个组件的源码依旧需要上下翻阅。 不过Composition API的出发点应该不仅仅是复用逻辑, image 也许是水平不到位,但是目前在我看来代码逻辑收集的作用是极大的, 例如calendar这个组件,将validatedRangedate操作分离开来,或许会一定程度上更易读一些。不过这个组件本身逻辑不算复杂,类似于input这样的组件我觉得将各个功能点抽离开来,可读性和可维护性都会提升。 不过我很疑惑为什么大家都没这么做,不知道是不是有些点我没考虑到,如果有的话希望大佬可以答疑解惑下。

chaishi commented 2 years ago

例如calendar这个组件,将validatedRange和date操作分离开来,或许会一定程度上更易读一些。不过这个组件本身逻辑不算

看看 tdesign-vue(vue2) 的 Calendar,逻辑挺复杂的,交互也挺多

复杂,类似于input这样的组件我觉得将各个功能点抽离开来,可读性和可维护性都会提升。

逻辑复用,逻辑隔离,完全没有问题,支持。

chaishi commented 2 years ago

https://github.com/vuejs/vue-next/issues/5191 大家也可以在这个 issue 里面一起探讨 Vue3 最佳实践

chaishi commented 2 years ago

不是不搞重构,重构很重要,非常重要,特别需要有实力的小伙伴共同参与。 只是在做一件事情之前,我们需要先规划好,然后再行动。

如果 tdesign-vue-next 继续按照每个组件单独开发,单独重构的模式,组件复用率依旧会非常低。而 Composition API 提倡的正是如何更优雅地提高组件复用率。

稍后,我们会拉群沟通,感兴趣的小伙伴可以扫码加入

image

chaishi commented 2 years ago

@gaopeak Message 组件建议,移步这里:https://github.com/Tencent/tdesign-vue-next/issues/107

当前 issue 讨论 Vue3 重构计划以及 Composition API 最佳实践

vnues commented 2 years ago

领取alert

PengYYYYY commented 2 years ago

目前,正在讨论对一些基础的Hook,大家也可以熟悉一下项目。认领组件后如果有重构完成的,可以提PR,可能CR的时间会稍长。官方这边也会加快基础Hook的建设。也欢迎加入群探讨。

vnues commented 2 years ago

认领avatar组件

vnues commented 2 years ago

有些公共方法会出现一些不兼容的情况, 例如emitEvent这个,老版本的写法是用vm: ComponentPublicInstance的, 如果迁移到composition api上的话,getCurrentInstance获取到的是ComponentInternalInstance类型, 原本的$props和$emit都要改成props和emit。 类似于这种情况是在emitEvent后新起一个func保证兼容性以及方便后期统一替换,还是有别的方案呢?

emitEvent 是 Vue2 特有的写法,为了支持 <checkbox @change="xxx"/><checkbox :onChange="xxx" 两种写法。Vue3 不需要 emitEvent。 ⚠️ 看到 emitEvent 的地方,Vue3 组件内部直接执行 this.onChange(xxx) 即可。 ⚠️ @higuaifan @pengYYYYY

👌疏忽了对函数本身作用的思考,感谢提醒

这里还不能直接用emit(event)这样写,因为vue3的文档写着支持:onChange=xxx这种写法,还是要处理下兼容的

image

vnues commented 2 years ago

认领drawer组件

PsTiu commented 2 years ago

认领calendar组件

Blackn-L commented 2 years ago

认领 progress

uyarn commented 2 years ago

认领dropdown

ChrisLee0211 commented 2 years ago

认领List组件

zouhangwithsweet commented 2 years ago

认领 radio & switch

ChrisLee0211 commented 2 years ago

认领badge组件

qunbotop commented 2 years ago

认领 notification

ChrisLee0211 commented 2 years ago

认领slider组件

btea commented 2 years ago

认领 textarea & transfer

Chanzhaoyu commented 2 years ago

认领 message 认领 popup

Blackn-L commented 2 years ago

认领 anchor 和 breadcrumb

qunbotop commented 2 years ago

认领 message

zouhangwithsweet commented 2 years ago

认领 radio & switch

因为最近工作安排较多,radio 暂时没空重构,sorry

k1nz commented 2 years ago

认领 radio

cca313 commented 2 years ago

认领 tooltip

TabSpace commented 2 years ago

认领 tree