首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

感受Vue3的魔法力量

一、前言

近半年有幸参与了一个创新项目,由于没有任何历史包袱,所以选择了Vue3技术栈,总体来说感受如下:

setup语法糖摆脱了书写声明式的代码,用起来很流畅,提升不少效率;

可以通过Composition API(组合式API)封装可复用逻辑,将UI和逻辑分离,提高复用性,View层代码展示更清晰;

和Vue3更搭配的状态管理库Pinia,少去了很多配置,使用起来更便捷;

构建工具Vite,基于ESM和Rollup,省去本地开发时的编译步骤,但是build打包时还是会编译(考虑到兼容性);

必备VSCode插件Volar,支持Vue3内置API的TS类型推断,但是不兼容Vue2,如果需要在Vue2和Vue3项目中切换,比较麻烦;

当然也遇到一些问题,最典型的就是响应式相关的问题:

二、响应式篇

本篇主要借助watch函数,理解ref、reactive等响应式数据/状态,有兴趣的同学可以查看Vue3源代码部分加深理解。

watch数据源可以是ref (包括计算属性)、响应式对象、getter 函数、或多个数据源组成的数组

总结:

在Vue3中状态都是默认深层响应式的(情景七),嵌套的引用类型在取值(get)时一定是返回Proxy响应式对象;

watch数据源为响应式对象时(情景四、七、九),会隐式的创建一个深层侦听器,不需要再显示设置deep: true;

情景三和情景八两种情况下,必须显示设置deep: true,强制转换为深层侦听器;

情景五和情景七对比下,虽然写法完全相同,但是如果属性值为基本类型时是监听不到的,尤其是ts类型声明为any时,ide也不会提示告警,导致排查问题比较费力;

所以精确的ts类型声明很重要,否则经常会出现莫名其妙的watch不生效的问题;

ref值为基本类型时通过get\set拦截实现响应式;ref值为引用类型时通过将.value属性转换为reactive响应式对象实现;

deep会影响性能,而reactive会隐式的设置deep: true,所以只有明确状态数据结构比较简单且数据量不大时使用reactive,其他一律使用ref;

三、Props篇

设置默认值

双向绑定(多个值)

自定义组件

使用组件

单向数据流

大部分情况下应该遵循【单向数据流】原则,禁止子组件直接修改props,否则复杂应用下的数据流将变得混乱,极易出现bug且难排查;

直接修改props会有告警,但是如果props是引用类型,修改props内部值将不会有告警提示,因此应该有团队约定(第5条除外);

如果props为引用类型,赋值到子组件状态时,需要解除引用(第5条除外);

复杂的逻辑,可以将状态以及修改状态的方法,封装成自定义hooks或者提升到store内部,避免props的层层传递与修改;

一些父子组件本就紧密耦合的场景下,可以允许修改props内部的值,可以减少很多复杂度和工作量(需要团队约定固定场景)

四、逻辑/UI解耦篇

利用Vue3的Composition/组合式API,将某种逻辑涉及到的状态,以及修改状态的方法封装成一个自定义hook,将组件中的逻辑解耦,这样即使UI有不同的形态或者调整,只要逻辑不变,就可以复用逻辑。下面是本项目中涉及的一个真实案例-逻辑树组件,UI有2种形态且可以相互转化。

hooks部分的代码:useDynamicTree.ts

在不同组件中使用(UI1/UI2组件为递归组件,内部实现不再展开)

五、Pinia状态管理篇

将复杂逻辑的状态以及修改状态的方法提升到store内部管理,可以避免props的层层传递,减少props复杂度,状态管理更清晰

定义一个store(非声明式):User.ts

•在组件中使用

问题讨论

Vue2中可以做到逻辑与UI分离吗?如果有,有哪些缺点?

什么场景下可以约定允许修改props内部的值?

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230201A05W7000?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券