@vureact/compiler-core 1.6.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +22 -235
- package/README.md +23 -236
- package/lib/{chunk-SRBJ5B5X.esm.js → chunk-6MTN25KZ.esm.js} +1293 -919
- package/lib/{chunk-FLZ5AUPG.js → chunk-V7G7OQWK.js} +1408 -1034
- package/lib/cli.esm.js +3 -2
- package/lib/cli.js +11 -10
- package/lib/compiler-core.d.cts +72 -57
- package/lib/compiler-core.d.ts +72 -57
- package/lib/compiler-core.esm.js +2 -2
- package/lib/compiler-core.js +3 -3
- package/package.json +6 -4
package/README.en.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# @vureact/compiler-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Write in Vue 3, compile to React 18+ code.**
|
|
4
|
+
|
|
5
|
+
It is not only suitable for migrating Vue 3 projects to React, but is also committed to seamlessly integrating Vue's excellent mental model with React's ecosystem capabilities, directly producing **maintainable, evolvable, and production-ready** React code from Vue code.
|
|
4
6
|
|
|
5
7
|
[](https://vureact.top/en/)
|
|
6
|
-
[](https://www.npmjs.com/package/@vureact/compiler-core)
|
|
9
|
+
[](https://www.npmjs.com/package/@vureact/compiler-core)
|
|
8
10
|
[](https://nodejs.org/)
|
|
9
11
|
[](https://opensource.org/licenses/MIT)
|
|
10
12
|
[](https://vuejs.org/)
|
|
@@ -12,107 +14,21 @@ A compiler that allows you to write React 18+ applications using Vue 3 syntax.
|
|
|
12
14
|
|
|
13
15
|
English | [简体中文](./README.md)
|
|
14
16
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
This section will guide you through creating, compiling, and running your first VuReact project; alternatively, you can check out the [playground](https://codesandbox.io/p/github/vureact-js/example-crm-admin-backend/master).
|
|
18
|
-
|
|
19
|
-
After completion, you will clearly understand three things:
|
|
20
|
-
|
|
21
|
-
1. Under what conventions input SFCs can be stably converted
|
|
22
|
-
2. What the compiled directory structure looks like
|
|
23
|
-
3. The semantic correspondence between the output TSX and the original SFC
|
|
24
|
-
4. The compiler automatically analyzes and appends dependencies, eliminating the need to manually manage React hooks dependencies
|
|
25
|
-
|
|
26
|
-
## Step 0: Prepare the Directory
|
|
27
|
-
|
|
28
|
-
First, set up a minimal project (illustration):
|
|
17
|
+
## Introduction
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
my-app/
|
|
32
|
-
├─ src/
|
|
33
|
-
│ ├─ components/
|
|
34
|
-
│ │ └─ Counter.vue
|
|
35
|
-
│ ├─ main.ts
|
|
36
|
-
│ └─ index.css
|
|
37
|
-
├─ package.json
|
|
38
|
-
└─ vureact.config.js
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Step 1: Installation
|
|
19
|
+
`@vureact/compiler-core` is the core compilation package of VuReact, responsible for compiling Vue 3 SFC, script files, and style files into React 18+ JSX/TSX code ready for production.
|
|
42
20
|
|
|
43
|
-
|
|
21
|
+
## Installation
|
|
44
22
|
|
|
45
23
|
```bash
|
|
46
|
-
# Using npm
|
|
47
24
|
npm install -D @vureact/compiler-core
|
|
48
|
-
|
|
49
|
-
# Using yarn
|
|
50
|
-
yarn add -D @vureact/compiler-core
|
|
51
|
-
|
|
52
|
-
# Using pnpm
|
|
53
|
-
pnpm add -D @vureact/compiler-core
|
|
54
25
|
```
|
|
55
26
|
|
|
56
|
-
##
|
|
57
|
-
|
|
58
|
-
`src/components/Counter.vue`
|
|
59
|
-
|
|
60
|
-
```html
|
|
61
|
-
<template>
|
|
62
|
-
<section class="counter-card">
|
|
63
|
-
<h2>{{ props.title || title }}</h2>
|
|
64
|
-
<p>Count: {{ count }}</p>
|
|
65
|
-
<button @click="increment">+1</button>
|
|
66
|
-
<button @click="methods.decrease">-1</button>
|
|
67
|
-
</section>
|
|
68
|
-
</template>
|
|
69
|
-
|
|
70
|
-
<script setup lang="ts">
|
|
71
|
-
// @vr-name: Counter (Note: Tells the compiler what component name to generate)
|
|
72
|
-
import { computed, ref } from 'vue';
|
|
73
|
-
|
|
74
|
-
// You can also use macros to define component names
|
|
75
|
-
defineOptions({ name: 'Counter' });
|
|
76
|
-
|
|
77
|
-
// Define props
|
|
78
|
-
const props = defineProps<{ title?: string }>();
|
|
79
|
-
|
|
80
|
-
// Define emits
|
|
81
|
-
const emits = defineEmits<{
|
|
82
|
-
(e: 'change'): void;
|
|
83
|
-
(e: 'update', value: number): number;
|
|
84
|
-
}>();
|
|
85
|
-
|
|
86
|
-
const step = ref(1);
|
|
87
|
-
const count = ref(0);
|
|
88
|
-
const title = computed(() => `Counter x${step.value}`);
|
|
89
|
-
|
|
90
|
-
const increment = () => {
|
|
91
|
-
count.value += step.value;
|
|
92
|
-
emits('update', count.value);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const methods = {
|
|
96
|
-
decrease() {
|
|
97
|
-
count.value -= step.value;
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
</script>
|
|
101
|
-
|
|
102
|
-
<style lang="less" scoped>
|
|
103
|
-
@border-color: #ddd;
|
|
104
|
-
@border-radius: 8px;
|
|
105
|
-
@padding-base: 12px;
|
|
27
|
+
## Quick Start
|
|
106
28
|
|
|
107
|
-
|
|
108
|
-
border: 1px solid @border-color;
|
|
109
|
-
border-radius: @border-radius;
|
|
110
|
-
padding: @padding-base;
|
|
111
|
-
}
|
|
112
|
-
</style>
|
|
113
|
-
```
|
|
29
|
+
👉 **Full tutorial: [VuReact Website - Quick Start](https://vureact.top/en/guide/quick-start.html)**
|
|
114
30
|
|
|
115
|
-
|
|
31
|
+
### Configuration Example
|
|
116
32
|
|
|
117
33
|
`vureact.config.ts`
|
|
118
34
|
|
|
@@ -120,164 +36,35 @@ pnpm add -D @vureact/compiler-core
|
|
|
120
36
|
import { defineConfig } from '@vureact/compiler-core';
|
|
121
37
|
|
|
122
38
|
export default defineConfig({
|
|
123
|
-
input: 'src',
|
|
124
|
-
// Key: Exclude Vue entry files to avoid entry semantic conflicts
|
|
39
|
+
input: './src',
|
|
125
40
|
exclude: ['src/main.ts'],
|
|
126
41
|
output: {
|
|
127
42
|
workspace: '.vureact',
|
|
128
|
-
outDir: '
|
|
129
|
-
|
|
130
|
-
// Recommended to enable in actual use
|
|
131
|
-
bootstrapVite: false,
|
|
43
|
+
outDir: 'react-app',
|
|
44
|
+
bootstrapVite: true,
|
|
132
45
|
},
|
|
133
46
|
});
|
|
134
47
|
```
|
|
135
48
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
### Method 1: Use the npx command
|
|
139
|
-
|
|
140
|
-
Run in the root directory:
|
|
49
|
+
### Commands
|
|
141
50
|
|
|
142
51
|
```bash
|
|
143
|
-
npx vureact build
|
|
52
|
+
npx vureact build # Build project
|
|
53
|
+
npx vureact watch # Watch mode
|
|
144
54
|
```
|
|
145
55
|
|
|
146
|
-
|
|
56
|
+
## Ecosystem
|
|
147
57
|
|
|
148
|
-
|
|
58
|
+
- **[VuReact Runtime Core](https://runtime.vureact.top/en)**: React-compatible implementations of Vue core APIs
|
|
59
|
+
- **[VuReact Router](https://router.vureact.top/en)**: Vue Router 4.x → React Router DOM 7.9+ conversion
|
|
149
60
|
|
|
150
|
-
|
|
151
|
-
"scripts": {
|
|
152
|
-
"watch": "vureact watch",
|
|
153
|
-
"build": "vureact build"
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
npm run build
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Step 5: View the Output Directory Tree
|
|
162
|
-
|
|
163
|
-
Compiled directory (illustration):
|
|
164
|
-
|
|
165
|
-
```txt
|
|
166
|
-
my-app/
|
|
167
|
-
├─ .vureact/
|
|
168
|
-
│ ├─ cache/
|
|
169
|
-
│ │ └─ _metadata.json
|
|
170
|
-
│ └─ dist/
|
|
171
|
-
│ └─ src/
|
|
172
|
-
│ └─ components/
|
|
173
|
-
│ ├─ Counter.tsx
|
|
174
|
-
│ └─ Counter-<hash>.css
|
|
175
|
-
├─ src/
|
|
176
|
-
│ └─ ...
|
|
177
|
-
└─ vureact.config.js
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Step 6: Compare the Generated Results
|
|
181
|
-
|
|
182
|
-
Below is a typical formatted output (slightly simplified for illustration; the actual hash and property names are subject to local output):
|
|
183
|
-
|
|
184
|
-
```tsx
|
|
185
|
-
import { memo, useCallback, useMemo } from 'react';
|
|
186
|
-
import { useComputed, useVRef } from '@vureact/runtime-core';
|
|
187
|
-
import './Counter-a1b2c3.css';
|
|
188
|
-
|
|
189
|
-
// Derived from defineProps and defineEmits
|
|
190
|
-
type ICounterType = {
|
|
191
|
-
title?: string;
|
|
192
|
-
onChange: () => void;
|
|
193
|
-
onUpdate: (value: number) => number;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// Component wrapped with memo
|
|
197
|
-
const Counter = memo((props: ICounterType) => {
|
|
198
|
-
// ref/computed converted to equivalent adaptation APIs
|
|
199
|
-
const step = useVRef(1);
|
|
200
|
-
const count = useVRef(0);
|
|
201
|
-
const title = useComputed(() => `Counter x${step.value}`);
|
|
202
|
-
|
|
203
|
-
// Automatically analyze dependencies of top-level arrow functions and append useCallback optimization
|
|
204
|
-
const increment = useCallback(() => {
|
|
205
|
-
count.value += step.value;
|
|
206
|
-
props.onUpdate?.(count.value); // emits conversion
|
|
207
|
-
}, [count.value, step.value, props.onUpdate]);
|
|
208
|
-
|
|
209
|
-
// Automatically analyze dependencies in top-level objects and append useMemo optimization
|
|
210
|
-
const methods = useMemo(
|
|
211
|
-
() => ({
|
|
212
|
-
decrease() {
|
|
213
|
-
count.value -= step.value;
|
|
214
|
-
},
|
|
215
|
-
}),
|
|
216
|
-
[count.value, step.value],
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<>
|
|
221
|
-
<section className="counter-card" data-css-a1b2c3>
|
|
222
|
-
<h2 data-css-a1b2c3>{props.title || title.value}</h2>
|
|
223
|
-
<p data-css-a1b2c3>Count: {count.value}</p>
|
|
224
|
-
<button onClick={increment} data-css-a1b2c3>
|
|
225
|
-
+1
|
|
226
|
-
</button>
|
|
227
|
-
<button onClick={methods.decrease} data-css-a1b2c3>
|
|
228
|
-
-1
|
|
229
|
-
</button>
|
|
230
|
-
</section>
|
|
231
|
-
</>
|
|
232
|
-
);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
export default Counter;
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
CSS file content:
|
|
239
|
-
|
|
240
|
-
```css
|
|
241
|
-
.counter-card[data-css-a1b2c3] {
|
|
242
|
-
border: 1px solid #ddd;
|
|
243
|
-
border-radius: 8px;
|
|
244
|
-
padding: 12px;
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Key Observations
|
|
249
|
-
|
|
250
|
-
1. The special comment `// @vr-name: Counter` defines the component name
|
|
251
|
-
2. `defineProps` and `defineEmits` are converted to TS component types
|
|
252
|
-
3. Non-pure UI display components are wrapped with `memo` by default
|
|
253
|
-
4. `ref` / `computed` are converted to runtime adaptation APIs (`useVRef` / `useComputed`)
|
|
254
|
-
5. Template event callbacks generate React-semantic `onClick`
|
|
255
|
-
6. Top-level arrow functions have their dependencies automatically analyzed and `useCallback` is injected where applicable
|
|
256
|
-
7. Top-level variable declarations have their dependencies automatically analyzed and `useMemo` is injected where applicable
|
|
257
|
-
8. The `.value` suffix is added to original `ref` state values in JSX
|
|
258
|
-
9. Less styles are compiled to CSS code
|
|
259
|
-
10. Scoped styles generate hashed CSS files and add scoped attributes to elements
|
|
61
|
+
If necessary, you can choose [☣️ Mixed Coding](https://vureact.top/en/guide/mind-control-readme.html) to directly use the React ecosystem.
|
|
260
62
|
|
|
261
63
|
## FAQ
|
|
262
64
|
|
|
263
|
-
|
|
264
|
-
- Calling APIs that are converted to Hooks outside the top level
|
|
265
|
-
- Unanalyzable expressions appearing in templates (triggering warnings)
|
|
266
|
-
- Disabling style preprocessing while using `scoped`, leading to scoping failure
|
|
267
|
-
|
|
268
|
-
For more details, please refer to the [FAQ](https://vureact.top/guide/en/faq.html) of the official documentation.
|
|
269
|
-
|
|
270
|
-
## Ecosystem Integration
|
|
271
|
-
|
|
272
|
-
- **[VuReact Runtime Core](https://runtime.vureact.top/en)**: Provides React versions of Vue's common built-in components, core Composition API, etc.
|
|
273
|
-
- **[VuReact Router](https://router.vureact.top/en)**: Supports conversion from Vue Router 4.x to React Router DOM 7.9+.
|
|
274
|
-
|
|
275
|
-
If necessary, you can choose [☣️ Mixed Coding](https://vureact.top/guide/mind-control-readme.html) to directly use the React ecosystem.
|
|
65
|
+
👉 [FAQ](https://vureact.top/en/guide/faq.html)
|
|
276
66
|
|
|
277
67
|
## 🔗 Links
|
|
278
68
|
|
|
279
69
|
- GitHub: <https://github.com/vureact-js/core>
|
|
280
70
|
- Documentation: <https://vureact.top/en>
|
|
281
|
-
- Playground:
|
|
282
|
-
- CRM Admin Dashboard (Standard): <https://codesandbox.io/p/github/vureact-js/example-crm-admin-backend/master>
|
|
283
|
-
- Customer Support Hub (Mixed): <https://codesandbox.io/p/github/vureact-js/example-customer-support-hub/master?import=true>
|
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# @vureact/compiler-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**写 Vue,生成可维护的 React**
|
|
4
|
+
|
|
5
|
+
它不仅适用于 Vue 3 到 React 项目的迁移,更致力于将 Vue 优秀的心智模型与 React 生态能力无缝融合,用 Vue 代码直接产出**可维护、可演进、生产就绪**的 React 代码。
|
|
4
6
|
|
|
5
7
|
[](https://vureact.top/)
|
|
6
|
-
[](https://www.npmjs.com/package/@vureact/compiler-core)
|
|
9
|
+
[](https://www.npmjs.com/package/@vureact/compiler-core)
|
|
8
10
|
[](https://nodejs.org/)
|
|
9
11
|
[](https://opensource.org/licenses/MIT)
|
|
10
12
|
[](https://vuejs.org/)
|
|
@@ -12,107 +14,21 @@
|
|
|
12
14
|
|
|
13
15
|
简体中文 | [English](./README.en.md)
|
|
14
16
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
本节将引导你完成第一个 VuReact 项目的创建、编译和运行;或者选择查看 [CodeSandbox 在线案例](https://codesandbox.io/p/github/vureact-js/example-crm-admin-backend/master)。
|
|
18
|
-
|
|
19
|
-
完成后你会明确三件事:
|
|
17
|
+
## 简介
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
2. 编译后目录会长什么样
|
|
23
|
-
3. 输出 TSX 与原始 SFC 的语义对应关系
|
|
24
|
-
4. 编译器会自动分析并追加依赖,无需手动管理 React hooks 依赖项
|
|
25
|
-
|
|
26
|
-
## Step 0:准备目录
|
|
27
|
-
|
|
28
|
-
先准备一个最小工程(示意):
|
|
29
|
-
|
|
30
|
-
```txt
|
|
31
|
-
my-app/
|
|
32
|
-
├─ src/
|
|
33
|
-
│ ├─ components/
|
|
34
|
-
│ │ └─ Counter.vue
|
|
35
|
-
│ ├─ main.ts
|
|
36
|
-
│ └─ index.css
|
|
37
|
-
├─ package.json
|
|
38
|
-
└─ vureact.config.js
|
|
39
|
-
```
|
|
19
|
+
`@vureact/compiler-core` 是 VuReact 的核心编译包,负责将 Vue 3 单文件组件、脚本文件和样式文件**三位一体**编译为可直接用于生产环境的 React 18+ JSX/TSX 代码。
|
|
40
20
|
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
在你的 Vue 项目中安装 VuReact 编译器:
|
|
21
|
+
## 安装
|
|
44
22
|
|
|
45
23
|
```bash
|
|
46
|
-
# 使用 npm
|
|
47
24
|
npm install -D @vureact/compiler-core
|
|
48
|
-
|
|
49
|
-
# 使用 yarn
|
|
50
|
-
yarn add -D @vureact/compiler-core
|
|
51
|
-
|
|
52
|
-
# 使用 pnpm
|
|
53
|
-
pnpm add -D @vureact/compiler-core
|
|
54
25
|
```
|
|
55
26
|
|
|
56
|
-
##
|
|
57
|
-
|
|
58
|
-
`src/components/Counter.vue`
|
|
59
|
-
|
|
60
|
-
```html
|
|
61
|
-
<template>
|
|
62
|
-
<section class="counter-card">
|
|
63
|
-
<h2>{{ props.title || title }}</h2>
|
|
64
|
-
<p>Count: {{ count }}</p>
|
|
65
|
-
<button @click="increment">+1</button>
|
|
66
|
-
<button @click="methods.decrease">-1</button>
|
|
67
|
-
</section>
|
|
68
|
-
</template>
|
|
69
|
-
|
|
70
|
-
<script setup lang="ts">
|
|
71
|
-
// @vr-name: Counter (注:用于告诉编译器,该生成什么组件名)
|
|
72
|
-
import { computed, ref } from 'vue';
|
|
73
|
-
|
|
74
|
-
// 也可以使用宏定义组件名
|
|
75
|
-
defineOptions({ name: 'Counter' });
|
|
76
|
-
|
|
77
|
-
// 定义 props
|
|
78
|
-
const props = defineProps<{ title?: string }>();
|
|
79
|
-
|
|
80
|
-
// 定义 emits
|
|
81
|
-
const emits = defineEmits<{
|
|
82
|
-
(e: 'change'): void;
|
|
83
|
-
(e: 'update', value: number): number;
|
|
84
|
-
}>();
|
|
85
|
-
|
|
86
|
-
const step = ref(1);
|
|
87
|
-
const count = ref(0);
|
|
88
|
-
const title = computed(() => `Counter x${step.value}`);
|
|
89
|
-
|
|
90
|
-
const increment = () => {
|
|
91
|
-
count.value += step.value;
|
|
92
|
-
emits('update', count.value);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const methods = {
|
|
96
|
-
decrease() {
|
|
97
|
-
count.value -= step.value;
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
</script>
|
|
101
|
-
|
|
102
|
-
<style lang="less" scoped>
|
|
103
|
-
@border-color: #ddd;
|
|
104
|
-
@border-radius: 8px;
|
|
105
|
-
@padding-base: 12px;
|
|
27
|
+
## 快速开始
|
|
106
28
|
|
|
107
|
-
|
|
108
|
-
border: 1px solid @border-color;
|
|
109
|
-
border-radius: @border-radius;
|
|
110
|
-
padding: @padding-base;
|
|
111
|
-
}
|
|
112
|
-
</style>
|
|
113
|
-
```
|
|
29
|
+
👉 **完整教程请访问:[VuReact - 快速开始](https://vureact.top/guide/quick-start.html)**
|
|
114
30
|
|
|
115
|
-
|
|
31
|
+
### 配置示例
|
|
116
32
|
|
|
117
33
|
`vureact.config.ts`
|
|
118
34
|
|
|
@@ -120,165 +36,36 @@ pnpm add -D @vureact/compiler-core
|
|
|
120
36
|
import { defineConfig } from '@vureact/compiler-core';
|
|
121
37
|
|
|
122
38
|
export default defineConfig({
|
|
123
|
-
input: 'src',
|
|
124
|
-
// 关键:排除 Vue 入口文件,避免入口语义冲突
|
|
39
|
+
input: './src',
|
|
125
40
|
exclude: ['src/main.ts'],
|
|
126
41
|
output: {
|
|
127
42
|
workspace: '.vureact',
|
|
128
|
-
outDir: '
|
|
129
|
-
|
|
130
|
-
// 实际使用时建议开启
|
|
131
|
-
bootstrapVite: false,
|
|
43
|
+
outDir: 'react-app',
|
|
44
|
+
bootstrapVite: true,
|
|
132
45
|
},
|
|
133
46
|
});
|
|
134
47
|
```
|
|
135
48
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
### 方式一:使用 npx 命令
|
|
139
|
-
|
|
140
|
-
在根目录下运行:
|
|
49
|
+
### 编译命令
|
|
141
50
|
|
|
142
51
|
```bash
|
|
143
|
-
npx vureact build
|
|
52
|
+
npx vureact build # 编译项目
|
|
53
|
+
npx vureact watch # 监听模式
|
|
144
54
|
```
|
|
145
55
|
|
|
146
|
-
### 方式二:使用 npm scripts
|
|
147
|
-
|
|
148
|
-
在 `package.json` 里添加脚本命令:
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
"scripts": {
|
|
152
|
-
"watch": "vureact watch",
|
|
153
|
-
"build": "vureact build"
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
npm run build
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Step 5:查看输出目录树
|
|
162
|
-
|
|
163
|
-
编译后目录(示意):
|
|
164
|
-
|
|
165
|
-
```txt
|
|
166
|
-
my-app/
|
|
167
|
-
├─ .vureact/
|
|
168
|
-
│ ├─ cache/
|
|
169
|
-
│ │ └─ _metadata.json
|
|
170
|
-
│ └─ dist/
|
|
171
|
-
│ └─ src/
|
|
172
|
-
│ └─ components/
|
|
173
|
-
│ ├─ Counter.tsx
|
|
174
|
-
│ └─ counter-<hash>.css
|
|
175
|
-
├─ src/
|
|
176
|
-
│ └─ ...
|
|
177
|
-
└─ vureact.config.js
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Step 6:对照生成结果
|
|
181
|
-
|
|
182
|
-
下面是一个格式化后的典型输出(为说明做了轻微简化,实际哈希与属性名以本地产物为准):
|
|
183
|
-
|
|
184
|
-
```tsx
|
|
185
|
-
import { memo, useCallback, useMemo } from 'react';
|
|
186
|
-
import { useComputed, useVRef } from '@vureact/runtime-core';
|
|
187
|
-
import './counter-a1b2c3.css';
|
|
188
|
-
|
|
189
|
-
// 根据 defineProps 和 defineEmits 推导
|
|
190
|
-
type ICounterType = {
|
|
191
|
-
title?: string;
|
|
192
|
-
onChange: () => void;
|
|
193
|
-
onUpdate: (value: number) => number;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// memo 包裹组件
|
|
197
|
-
const Counter = memo((props: ICounterType) => {
|
|
198
|
-
// ref/computed 转换成了对等的适配 API
|
|
199
|
-
const step = useVRef(1);
|
|
200
|
-
const count = useVRef(0);
|
|
201
|
-
const title = useComputed(() => `Counter x${step.value}`);
|
|
202
|
-
|
|
203
|
-
// 自动分析顶层箭头函数依赖,并追加 useCallback 优化
|
|
204
|
-
const increment = useCallback(() => {
|
|
205
|
-
count.value += step.value;
|
|
206
|
-
props.onUpdate?.(count.value); // emits 转换
|
|
207
|
-
}, [count.value, step.value, props.onUpdate]);
|
|
208
|
-
|
|
209
|
-
// 自动分析顶层对象中的依赖,并追加 useMemo 优化
|
|
210
|
-
const methods = useMemo(
|
|
211
|
-
() => ({
|
|
212
|
-
decrease() {
|
|
213
|
-
count.value -= step.value;
|
|
214
|
-
},
|
|
215
|
-
}),
|
|
216
|
-
[count.value, step.value],
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<>
|
|
221
|
-
<section className="counter-card" data-css-a1b2c3>
|
|
222
|
-
<h2 data-css-a1b2c3>{props.title || title.value}</h2>
|
|
223
|
-
<p data-css-a1b2c3>Count: {count.value}</p>
|
|
224
|
-
<button onClick={increment} data-css-a1b2c3>
|
|
225
|
-
+1
|
|
226
|
-
</button>
|
|
227
|
-
<button onClick={methods.decrease} data-css-a1b2c3>
|
|
228
|
-
-1
|
|
229
|
-
</button>
|
|
230
|
-
</section>
|
|
231
|
-
</>
|
|
232
|
-
);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
export default Counter;
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
CSS 文件内容:
|
|
239
|
-
|
|
240
|
-
```css
|
|
241
|
-
.counter-card[data-css-a1b2c3] {
|
|
242
|
-
border: 1px solid #ddd;
|
|
243
|
-
border-radius: 8px;
|
|
244
|
-
padding: 12px;
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## 关键观察点
|
|
249
|
-
|
|
250
|
-
1. `// @vr-name: Counter` 这段特殊注释定义了组件名
|
|
251
|
-
2. `defineProps` 和 `defineEmits` 被转换成了 TS 组件类型
|
|
252
|
-
3. 非纯 UI 展示组件,默认会走 `memo` 包装
|
|
253
|
-
4. `ref` / `computed` 被转换为 runtime 适配 API(`useVRef` / `useComputed`)
|
|
254
|
-
5. 模板事件回调会生成符合 React 语义的 `onClick`
|
|
255
|
-
6. 顶层箭头函数自动分析依赖,尝试注入 `useCallback`
|
|
256
|
-
7. 顶层变量声明自动分析依赖,尝试注入 `useMemo`
|
|
257
|
-
8. 对 JSX 中的原 `ref` 状态值补上 `.value`
|
|
258
|
-
9. `less` 样式被编译为 css 代码
|
|
259
|
-
10. `scoped` 样式会生成带哈希的 css 文件,并在元素上标注作用域属性
|
|
260
|
-
|
|
261
|
-
## 常见问题
|
|
262
|
-
|
|
263
|
-
- 没排除 Vue 入口文件,如 `src/main.ts`
|
|
264
|
-
- 在非顶层调用会被转换为 Hook 的 API
|
|
265
|
-
- 模板里出现不可分析表达式并被告警
|
|
266
|
-
- 关闭样式预处理且使用 `scoped`,导致作用域失效
|
|
267
|
-
|
|
268
|
-
更多请查阅官方文档的 [FAQ 章节](https://vureact.top/guide/faq.html)。
|
|
269
|
-
|
|
270
56
|
## 生态集成
|
|
271
57
|
|
|
272
58
|
- **[VuReact Runtime Core](https://runtime.vureact.top/)**:提供 React 版的 Vue 常用内置组件、核心 Composition API 等
|
|
273
|
-
- **[VuReact Router](https://router.vureact.top/)**:支持 Vue Router 4.x
|
|
59
|
+
- **[VuReact Router](https://router.vureact.top/)**:支持 Vue Router 4.x → React Router DOM 7.9+ 转换
|
|
274
60
|
|
|
275
61
|
如果确实需要,你可以选择 [☣️混合编写](https://vureact.top/guide/mind-control-readme.html),以此直接使用 React 生态。
|
|
276
62
|
|
|
63
|
+
## 常见问题
|
|
64
|
+
|
|
65
|
+
👉 请查阅[官网 FAQ 章节](https://vureact.top/guide/faq.html)
|
|
66
|
+
|
|
277
67
|
## 🔗 链接
|
|
278
68
|
|
|
279
69
|
- GitHub:<https://github.com/vureact-js/core>
|
|
280
70
|
- Gitee:<https://gitee.com/vureact-js/core>
|
|
281
|
-
-
|
|
282
|
-
- CodeSandbox 在线案例:
|
|
283
|
-
- 客户关系管理后台(标准):<https://codesandbox.io/p/github/vureact-js/example-crm-admin-backend/master>
|
|
284
|
-
- 客户支持协同后台(混写):<https://codesandbox.io/p/github/vureact-js/example-customer-support-hub/master?import=true>
|
|
71
|
+
- 文档:<https://vureact.top>
|