A few days ago I posted a “DevUI IN VUE TSX functional component practice”, mainly about how to use TSX, in Vue3 to achieve functional component writing.

Here’s a little bit more.

Reasons for using TSX

Code quality constraints

With TS, you can improve the quality of your development-side code…

Of course, I’m aware that this is done by forcing developers to use strong typing, and there can be death, but look at the positive side effects: enhanced abstraction, enhanced holism, code static error correction, etc.

If developers can cross that threshold, they can jump to another level.

Automatically generated during compilationd.tsfile

Assuming you have typescript packages installed in your project, run the following script:

npx tsc src/index.ts --outDir public -d
Copy the code

You should get a directory with the same structure as SRC, as shown below:

(Ignore the CSS file in the screenshot)

Here, behind TSC

  • The first parameter is the entry file
  • --outDirIs the output directory
  • -dIndicates that a declaration file is generated

Please note that TSC is a standalone, full-featured TS compilation tool that compiles entire projects based on entry files and reference dependencies and supports TSX. As for packaging, compression, is another matter.

If you publish as an NPM package with a d.ts file, VSCode will recurse all output types based on the d.ts corresponding to the entry file when referencing the package.

Many of the early packages released that didn’t have D.ts, or weren’t developed based on TS, were made up for with @types/ XXX additional NPM packages, such as @types/node.

In fact, the best part is that when the D.ts file is generated, not only the type of output module is extracted, but the JSDoc format comments are also extracted.

Also, JSDoc supports markdown writing, which means that comment prompts can be formatted.

type TProps = {
    /** * ###src? :string
    /** * ###width? :number
    /** * ###height? :number
    /** * ### fill mode * - 'stretch' is full * - 'cover' is full * - 'contain' is full */mode? :'stretch' | 'cover' | 'contain'
}
Copy the code

It’s very professional.

Weak code prompts for Vue files

Based on my experience with VUE in DevUI projects, the perception of.vue files, and the type of vue itself, there are limitations, and IDE support is not that good.

For example, the mode property of the Image component (props)

export default defineComponent({
    props: {
        mode: { type: String}}})Copy the code

Because vUE is behind the type inference, if in the js category, this method can also prompt the name of the attribute, underline attribute type error, in fact, is very nb. But when it comes to TS, it’s much weaker.

Let me write it this way in terms of TSX

export default (props: { mode: 'stretch' | 'cover' | 'contain'}) = ><img .>
Copy the code

In vUE writing, you can only restrict to large types like string, but ts allows you to validate enumerations more accurately, and the IDE can also list enumerations.

You don’t make me angry.

Why functional components

Learn from the React mature practice

When you write React, if you write a class component, it looks something like this

import React from 'react'
export class extends React.Component<{ mode? :string} > {/ /...
}
Copy the code

You can see that the component actually has dependencies on the React package.

Functional components, however, are different

import React from 'react'
export default(props: { mode? :string}) = ><img mode={props.mode} />
Copy the code

The react reference is actually a legacy issue, and the function component itself has no dependency on React.

However, it is this legacy problem that causes an error if there is no React reference when babel-loader parses JSX.

The @vue/babel-plugin-jsx plug-in mentioned in the previous article solves this problem, so that the component can become purely:

export default(props: { mode? :string}) = ><img mode={props.mode} />
Copy the code

IDE’s good support for functional components

We can abstract this functional component into a type

type TVueFuncComponent<TProps> = (props: TProps) = > JSX.Element
Copy the code

Here’s the thing: VSCode is very friendly to support this functional component type.

In the existing vUE writing method, it is based on props to make type speculation, and there is no official release of functional component writing method.

Vue functional component implementation method

Two of these were listed in the previous article, and are summarized here into three components:

Stateless component

export default(props: { mode? :string}) = ><img mode={props.mode} />
Copy the code

This is not to say, familiar with JSX syntax is good.

Stateful component

Higher-order functions

import { reactive } from 'vue'

const factory = () = > {
    const state = reactive({ count: 0 })
    return (props: TProps) = > {
        return <button onClick={()= > state.count += 1}>
            Click me {state.count} times
        </button>}}export default factory()
Copy the code

Life cycle control

High order component

import { onMounted, defineComponent } from 'vue'

const Comp = defineComponent({
    props: {
        mode: { type: String}},setup(props) {
        return () = > <img mode={props.mode} />}})export default (props: TProps) => <Comp { . props} / >
Copy the code

Since all three types can be output as TVueFuncComponent

, the IDE resolves d.ts as a functional JSX component, which makes perfect code prompting.

JSX components can only be prompted if they are referenced in JSX, not in template in the.vue file, which is not JSX.

The above.