Preface
Recently, a Vue3 framework that supports IOC containers was released: Zova. Unlike previous OOP or Class solutions, Zova still uses Setup syntax at the ui interaction side and only introduces IOC containers at the business side. IOC containers are like a key that opens the door to business engineering for us, allowing us to explore more engineering designs and capabilities.
A netizen made a very good suggestion: Can you provide some business scenarios to explain what Class can do but Composable can't do, so that it will be more convincing.
First of all, it should be noted that there are actually no business requirements that can be done by this and not by that. Different programming paradigms bring different code styles and different programming experiences, pointing to the evaluation of development efficiency and code maintainability from different paths. Therefore, it ultimately depends on the user's own habits and actual business requirements.
So, here, we will take this topic How to provide types for route query parameters in Vue3
as an example to see what the code styles of Composable and IOC containers are different.
Business requirements
Here is a page component User
, which can pass three parameters through Query
:
Param | Type | Default |
---|---|---|
id | number | 0 |
name | string | '' |
married | boolean | false |
Composable: native
1. Open page
const router = useRouter();
router.push({
path: '/test/demo/user',
query: {
id: 1,
name: 'kevin',
married: false.toString(),
},
});
From the perspective of Typescript types, this code has the following two problems:
-
path: no type constraints and autocompletion
. This will have the following three hidden dangers:-
Can't remember
: If the path is long or the words are complex, you can't remember the path and need to find it from the source file -
Written wrong
: If you accidentally write it wrong, there is no prompt, and the error will only be exposed when it is actually run -
Changed
: If the path is changed during subsequent code maintenance, there will be no prompt in the code here, and the error will only be exposed when it is actually run
-
-
query: only limited type constraints, inconsistent with business types
- For example,
Boolean
type is not supported and must be forced toString
type
- For example,
2. Obtain parameters
const route = useRoute();
const id = parseInt(route.query.id ?? 0);
const name = route.query.name ?? '';
const married = route.query.married === 'true' ? true : false;
Since no type tool is provided, each parameter needs to be processed separately
Composable:useRouteQuery
1. Open page
(Same as above)
2. Obtain parameters
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 container
1. Define types
import { zz } from 'zova';
export const QuerySchema = zz.object({
+ id: zz.number().default(0),
+ name: zz.string().default(''),
+ married: zz.boolean().default(false),
});
-
zz
is an enhanced version based onzod
, which is specially processed for route parameters and supportsarray
andjson
. For details, see: Zova: zod - You can specify the default value when defining the types
2. Open page
const url = this.$router.resolvePath('/test/demo/user', {
id: 0,
name: 'kevin',
married: false,
});
this.$router.push(url);
- The parameters of
resolvePath
have type constraints and autocompletion, and are consistent with the business types
3. Obtain parameters
const id = this.$query.id;
const name = this.$query.name;
const married = this.$query.married;
- Get parameter values directly through
this.$query
, with precise types and no need to handle default values
Conclusion
From the above example comparison, we can see that the IOC container can separate the definition
from the usage
, and the scaffolding can be created by tools on the definition side to further simplify the writing of the definition. Since the normative codes such as TS types and default values are completed on the definition side, the code on the usage side is more concise and intuitive. I don't know what your code style is, and if there is a better way to implement it, you are welcome to communicate in the comment area.
Top comments (0)