久趣下载站

当前位置: 首页 » 游戏攻略 » 深度比较:Composable 和 IOC容器在Vue3中的应用

深度比较:Composable 和 IOC容器在Vue3中的应用

最近发布了一款支持IOC容器的Vue3框架:Zova。与以往的OOP或者Class方案不同,Zova在界面交互层面仍然采用Setup语法,仅仅在业务层面引入IOC容器。IOC容器犹如一把钥匙,为我们打开了业务工程化的大门,允许我们探索更多工程化方面的设计和能力。有网友提出一个非常好的建议:可否提供一些业务场景,说明有哪些是Class可做而Composable做不了的,这样才更有说服力。

首先说明一点,其实没有哪些业务需求是这个能做而那个不能做的。不同的编程范式带来的是不同的代码风格,不同的编程体验,从不同的路径指向开发效率和代码可维护性方面的评估。因此,最终根据用户自身的偏好和业务实际需求而定。

那么,在这里,我们就针对这个话题,如何为路由Query参数标注类型,为例,看看Composable和IOC容器的代码风格究竟有什么不同。

需求说明

这里有一个页面组件User,可以通过Query传递三个参数:

参数名 类型 缺省值
id number 0
name string
married boolean false

Composable:原生

1. 访问页面

const router = useRouter();

router.push({

path: ‘/test/demo/user’,

query: {

id: 1,

name: ‘kevin’,

married: false.toString(),

},

});

从Typescript类型的角度来看,这段代码有以下两个问题:


  1. path:没有类型约束和智能提示

    。这会存在以下三个隐患:


    1. 记不住

      :如果路径较长,或者单词较复杂,就记不住路径,需要从源文件查找

    2. 写错了

      :如果不小心写错了,没有提示,只有到实际运行时才会暴露错误

    3. 被改了

      :如果后续维护代码时,路径有了变更,那么这里的代码同样没有提示,只有到实际运行时才会暴露错误

  2. query:只有有限的类型约束,与业务类型并不一致

    1. 比如不支持Boolean类型,必须强制转换为String类型

2. 获取参数

const route = useRoute();

const id = parseInt(route.query.id ?? 0);

const name = route.query.name ?? ”;

const married = route.query.married === ‘true’ ? true : false;

由于没有提供类型工具,需要针对每一个参数单独处理

Composable:useRouteQuery

1. 访问页面

(同上)

2. 获取参数

import { useRouteQuery } from ‘@vueuse/router’;

const id = useRouteQuery(‘id’, 0, { transform: Number });

const name = useRouteQuery(‘name’, ”);

const married = useRouteQuery(‘married’, ‘false’, {

transform: value => {

return value === ‘true’ ? true : false;

},

});

IOC容器

1. 定义类型

import { zz } from ‘zova’;

export const QuerySchema = zz.object({

id: zz.number().default(0),

name: zz.string().default(”),

married: zz.boolean().default(false),

});

  • zz是在zod基础上做的加强版,特别针对路由参数做了处理,支持array数组和json对象,具体参见:
    Zova: zod
  • 在定义类型的同时可以指定缺省值

2. 访问页面

const url = this.$router.resolvePath(‘/test/demo/user’, {

id: 0,

name: ‘kevin’,

married: false,

});

this.$router.push(url);

  • resolvePath的参数都有类型约束和智能提示,并且与业务类型保持一致

3. 获取参数

const id = this.$query.id;

const name = this.$query.name;

const married = this.$query.married;

  • 直接通过

    this.$query

    获取参数值,有明确的类型,并且不需要处理缺省值

总结

从上面的示例对比可以看出,采用IOC容器,可以实现

定义



使用

的分离,而且

定义

侧可以通过工具来创建脚手架,进一步简化

定义

的书写。由于TS类型和缺省值等规范性代码都在

定义

侧完成了,那么在

使用

侧代码就更加简洁直观了。不知您的代码风格偏好是什么,是否还有更好的表达方式,欢迎在评论区交流。

参考资料

  • VueUse: useRouteQuery
  • Zova: 路由Query
猜你喜欢
本类排行