background
As a popular front-end framework, Vue provides a variety of ways to define components, including single file components (SFC), rendering functions, JSX/TSX, and Functional Components. Different methods are suitable for different scenarios, and developers need to consider factors such as readability, performance and flexibility when choosing. This article will compare these four methods in detail to help you find the most suitable solution for your project.
1. SFC (Single-File Component)
single file component,*.vue
As a file extension, it is the official recommended method by Vue.
Features:
- The templates and logic are separated, the structure is clear, and the official recommendation is.
- Supports built-in Vue functions such as
script setup
, CSS scope, single file component hot update, etc. - Suitable for most Vue projects, the code organization is more intuitive.
The code is as follows:
<script setup lang="ts"> import { ref } from "vue"; defineProps<{ text: string; }>(); const num = ref(0); </script> <template> <div class="aaa"> {{ text }} <div @click="num++">{{ num }}</div> </div> </template>
advantage:
- The code structure is clear, conforms to the MVVM mode, and the template part is easy to read.
-
script setup
Provides a cleaner syntax, reducing code switching between templates and logic. - It has good toolchain support (Vue official ecosystem, Vite, Vue Loader, etc.).
shortcoming:
- Additional build tools (such as Vite or Webpack) are required to compile and cannot be run directly in the browser.
- In some scenarios (such as dynamically creating components) it may be less flexible than rendering functions.
2. Render Functions
Vue provides ah()
Functions are used to create virtual nodesvnodes
。
Features:
- Need to be introduced
h
anddefineComponent
Function, no template syntax. - Suitable for dynamic component or UI library development.
h is a helper function that creates a virtual DOM (VNode). It is an alias for createElement, similar to those in React.
The code is as follows:
import { defineComponent, h, ref } from "vue"; export default defineComponent({ props: { text: { type: String, required: true } }, setup(props) { const num = ref(0); return () => h("div", { class: "aaa" }, [, h("div", { onClick: () => ++ }, )]); } });
advantage:
- The code is more flexible and is suitable for scenarios where VNode structure needs to be dynamically controlled, such as form renderers, drag-and-drop components, etc.
- Smaller size and no SFC parser is required.
shortcoming:
- The code is low readability, no template syntax, and the maintenance cost is high when writing complex components.
- The development experience is not as friendly as SFC, especially for developers who are not familiar with JSX/TSX.
3. JSX / TSX
JSX and TSX are syntax extensions of React, and Vue also supports this syntax.
Features:
- The syntax is similar to React, allowing the use of JSX/TSX syntax in Vue components.
- Suitable for more flexible logical processing without the need for introduction
h()
function.
Required configuration:
{ "compilerOptions": { "jsx": "preserve", "jsxImportSource": "vue" // ... } }
Requires configuration
vueJsx
Plugin:
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import vueJsx from "@vitejs/plugin-vue-jsx"; export default defineConfig({ plugins: [vue(), vueJsx()] // ... });
The code is as follows:
import { defineComponent, ref } from "vue"; export default defineComponent({ props: { text: { type: String, required: true } }, setup(props) { const num = ref(0); return () => ( <div class="aaa"> {} <div onClick={() => ++}>{}</div> </div> ); } });
advantage:
- Flexible code, suitable for complex UI component development.
- Have better type derivation support in TypeScript projects.
shortcoming:
- Need extra
@vitejs/plugin-vue-jsx
Plugins are supported and inConfigure JSX options.
- The code style does not conform to Vue's traditional template syntax and may not be suitable for all teams.
4. Functional Components — Not recommended
Features:
- Components are essentially pure functions.
ref
It can only be defined outside the component and belongs to the global shared state. - Suitable for dependency only
props
A component that does rendering and stateless.
The code is as follows:
import { ref, type FunctionalComponent } from "vue"; interface Props { text: string; } const num = ref(0); export const TestFunctionalCom: FunctionalComponent<Props> = (props) => { return ( <div class="aaa"> {} <div onClick={() => ++}>{}</div> </div> ); };
advantage:
- The code is simple and suitable for simple display components (such as buttons, icons, etc.).
- There is no responsive data tracking overhead and higher performance.
shortcoming:
- Cannot be used inside components
ref
orreactive
, the state must be a global variable orprops
Incoming. - Global
ref
This may cause multiple component instances to share state, causing unexpected state synchronization issues.
Summarize
Way | Applicable scenarios | advantage | shortcoming |
---|---|---|---|
SFC (Single File Component) | Suitable for most Vue projects | Clear structure, official recommendation, supportscript setup
|
Need a build tool |
Render Functions | Suitable for dynamic components/UI libraries | More flexible code, suitable for dynamic VNode structures | Low readability and high maintenance cost |
JSX / TSX | Suitable for complex logic components | Flexible code, can be combined with TypeScript | Requires additional configuration and does not comply with the traditional Vue syntax |
Functional Components | Suitable for stateless widgets | Simple code, high performance | Cannot be usedref , global state sharing is risky |
In actual development,SFC is the most recommended way, most Vue components can be implemented using SFC. For dynamic VNode structures, considerRendering functionsorJSX/TSX。Functional ComponentsThere are few usage scenarios in Vue 3 and are usually not recommended.
The above is the detailed content of the four ways to define components in Vue3. For more information about Vue3, please pay attention to my other related articles!