vue3 最佳实践

8,071 阅读7分钟

vue3很棒的新特性

以上是我认为 vue3 非常重要,也非常棒的特性。当然vue3还有很多新特性也没必要一一列举,感兴趣自己去读官网就好了。

vue3 真正的威力——函数式编程

先来看一下 vue2.x 时常见的代码形式吧

这样看其实没什么问题,但是某一天需要复用一段逻辑时,就开始头疼了,因为你会发现一段完整的逻辑散落在 data、methods、watch、computed…… 里,得一个个小心的提取。

接下来阻碍你的更大问题来了—— this,vue2.x里到处都是this(因为vue靠this上下文暴露property)。所以在2下,我们的组件通常都是完整的自闭合组件,复用通常是针对一个完整的组件或一些完全无状态的util函数,组件内部的逻辑是很难复用的。

如果某一段逻辑你非要复用,而你又不想copy一个新的组件,那恶心的事情就来了,你得向组件注入一些参数去控制它。

接下来发现组件间有大量通信、共享状态的需求,单靠vue的父子组件传参以及无法满足复杂的需求了,开始引入 vuex 这种状态管理库,但是我们只是从表面上解决了数据、状态混乱的问题,并没有从根本上解决问题(逻辑的复用、更简单的使用vue、更纯粹的组件)。

我们思考一下在vue2时的代码,会不会有一种vue不咋灵活的感觉(没有的同学可以思考一下如何用vue2写一个高阶组件)。

vue3时代

这是我从业务中截取的一段Botton组件代码,仔细观察有没有发现一些不一样,没错,整个组件都是无状态的了,核心代码 setStep 已经被提取复用了

其他组件通过订阅 step 来完成逻辑通信,提取、复用组件内部逻辑有什么意义呢?我们接下来看这样一段代码

红色线框内就是被复用的各种逻辑,我们已经将业务逻辑封装在了三大函数内,大家不用纠结逻辑细节,感受这种编码风格,是不是有点像react hooks,这是我特意这样写的,包括下面的 init 函数,也是可以作为包装函数被复用。

vue3 之下,我们可以把相关代码维护在一起,代码空间距离更低,可读性高。

vue3 暴露了很多核心能力,像 computed、onMounted、watch等都通过函数的形式暴露了出来,这对我目前的编辑器插件系统设计带来了很强的思考。

很多人会觉得 vue3 像 hooks,特别是如果看了我上面的例子可能更觉得像,先申明,上面的例子我是故意按照 hooks 的风格编写的,vue3并没有要求、建议我们这样使用,只是我觉得这样写比较直观。

听说vue3之下不再需要 vuex,目前我感觉确实不太需要 vuex,因为我们已经可以很方便的提取组件逻辑,并通过响应式变量驱动业务,跨组件通信也完成了。当然复杂模型下,vuex还是很有用的。

这是我提取的业务逻辑,作用可以约等于 vuex 模式下的store。

不建议使用的 vue3 特性

teleport

teleport 允许开发者将组件脱离正常的组件流,然后插入特定位置,类似js中的 document.body.appendChild()。 参考被很多语言放弃的 goto(java)语法,我认为应该要能通过dom结构还原组件树结构(你在哪引用的组件,它就应该出现在对应的位置上,如果你需要在某个div内引用一个组件,却要把它插入到body下,那说明这个组件就不应该在div中引用),工程中使用 teleport 会导致代码可读性降低,并人为制造混乱。teleport 完全可以通过高阶组件或者良好的组件拆分、复用实现类似功能。

它典型的应用场景之一有弹窗,不建议使用也不是一棒子打死不能用,只是绝大多数场景不要用。

vue3 引发的思考

如果大家搜索 “vue3 特性 优点 好处” 这类关键词,得到的绝大多数回答都是性能提升、composition API、proxy响应式、diff的优化、体积变小、更好的支持ts……

这些改变非常棒,但是绝不足以支持大部分用户替换vue3,也不是作者的终极目标,因为它们都 “太小” 了。

我认为 vue3 带来的是编程思路的改变 —— 以函数式的思想编程。

我曾经参与过多个老项目的重构,最痛苦的不是代码缺乏注释、可读性差、历史包袱,而是牵一发动全身如印度电线一般的依赖关系。

因为重构意味着我需要阅读完全部的依赖图谱,这几乎无法下手。但是就想,如果买个模块都只专注自己的领域多好,像流水线车间一样,做铁钉的车间只接受标准铁块,永远只输出铁钉,除此之外再无其他。多年后明白了,这就是函数式编程思维。

如果不能理解这种思想,那可能很难理解 vue3 为什么要以函数的形式提供生命周期的能力、甚至vue3为什么会存在

好像面向对象还没理解,现在又搞什么函数式,其实无论是哪种模式,都是对于现实世界某种社会形式的抽象,目的都是为了能降低大家理解编程思维的成本。因为底层的代码是命令式的,很难理解,所以人们不断的提供高阶的抽象,所以它们两对比没有什么意义。

函数式编程的文章太多,这里只是抛砖引玉,希望能帮大家引入一种新的思维方式。

开发者的思维局限性

大家思考一个问题,为什么网上大量都是对vue3技术层面的分析,为什么少见对于它诞生目的、为何而来的思考?

这是技术人员常见的一个通病,相信在业务线呆过的同学应该都领导说过这样一句话:技术固然重要(不要埋头搞技术),也要善于挖掘需求的价值(也要挖挖思想根源),其实是想要你能通过现象看本质。

大到一个产品小到一个函数,很多人都可以分析出它的原理、执行机制,但是少有人能理解为什么它会存在(假定存在即合理),它到底解决了社会上的哪些问题。

番外

这里是我自己总结的 vue3 最佳实践,期间阅读了大量 element-ui plus (element 团队接触vue3应该是国内比较早的)的代码,也总结react的一些书写习惯(我提取的hooks就有很明显的 react 痕迹),并且在公司内部项目进行了落地、推广。

细心的同学可能会发现我的 setup 基本只有一个 return 逻辑代码都被提取出去了,我这么做的目的是不希望写出一个巨大无比的 setup,这是从代码可读性角度考虑的,所以能提出去的我都不会放在 setup 里。

element-ui plus 就是把代码都写 setup 里维护(可以看一下他们的 input组件),我是非常不喜欢维护一个巨大无比的函数。

最后

vue3 截止目前我也才用了2个月不到,随着阅历的增加会不断重建我对它的看法,欢迎大家一起来探讨