You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
6.7 KiB

3 months ago
  1. # Babel Plugin JSX for Vue 3
  2. [![npm package](https://img.shields.io/npm/v/@vue/babel-plugin-jsx.svg?style=flat-square)](https://www.npmjs.com/package/@vue/babel-plugin-jsx)
  3. [![issues-helper](https://img.shields.io/badge/Issues%20Manage%20By-issues--helper-blueviolet?style=flat-square)](https://github.com/actions-cool/issues-helper)
  4. To add Vue JSX support.
  5. English | [简体中文](/packages/babel-plugin-jsx/README-zh_CN.md)
  6. ## Installation
  7. Install the plugin with:
  8. ```bash
  9. npm install @vue/babel-plugin-jsx -D
  10. ```
  11. Then add the plugin to your babel config:
  12. ```json
  13. {
  14. "plugins": ["@vue/babel-plugin-jsx"]
  15. }
  16. ```
  17. ## Usage
  18. ### options
  19. #### transformOn
  20. Type: `boolean`
  21. Default: `false`
  22. transform `on: { click: xx }` to `onClick: xxx`
  23. #### optimize
  24. Type: `boolean`
  25. Default: `false`
  26. enable optimization or not. It's not recommended to enable it If you are not familiar with Vue 3.
  27. #### isCustomElement
  28. Type: `(tag: string) => boolean`
  29. Default: `undefined`
  30. configuring custom elements
  31. #### mergeProps
  32. Type: `boolean`
  33. Default: `true`
  34. merge static and dynamic class / style attributes / onXXX handlers
  35. #### enableObjectSlots
  36. Type: `boolean`
  37. Default: `true`
  38. Whether to enable `object slots` (mentioned below the document) syntax". It might be useful in JSX, but it will add a lot of `_isSlot` condition expressions which increase your bundle size. And `v-slots` is still available even if `enableObjectSlots` is turned off.
  39. #### pragma
  40. Type: `string`
  41. Default: `createVNode`
  42. Replace the function used when compiling JSX expressions.
  43. #### resolveType
  44. Type: `boolean`
  45. Default: `false`
  46. (**Experimental**) Infer component metadata from types (e.g. `props`, `emits`, `name`). This is an experimental feature and may not work in all cases.
  47. ## Syntax
  48. ### Content
  49. functional component
  50. ```jsx
  51. const App = () => <div>Vue 3.0</div>;
  52. ```
  53. with render
  54. ```jsx
  55. const App = {
  56. render() {
  57. return <div>Vue 3.0</div>;
  58. },
  59. };
  60. ```
  61. ```jsx
  62. import { withModifiers, defineComponent } from 'vue';
  63. const App = defineComponent({
  64. setup() {
  65. const count = ref(0);
  66. const inc = () => {
  67. count.value++;
  68. };
  69. return () => (
  70. <div onClick={withModifiers(inc, ['self'])}>{count.value}</div>
  71. );
  72. },
  73. });
  74. ```
  75. Fragment
  76. ```jsx
  77. const App = () => (
  78. <>
  79. <span>I'm</span>
  80. <span>Fragment</span>
  81. </>
  82. );
  83. ```
  84. ### Attributes / Props
  85. ```jsx
  86. const App = () => <input type="email" />;
  87. ```
  88. with a dynamic binding:
  89. ```jsx
  90. const placeholderText = 'email';
  91. const App = () => <input type="email" placeholder={placeholderText} />;
  92. ```
  93. ### Directives
  94. #### v-show
  95. ```jsx
  96. const App = {
  97. data() {
  98. return { visible: true };
  99. },
  100. render() {
  101. return <input v-show={this.visible} />;
  102. },
  103. };
  104. ```
  105. #### v-model
  106. > Note: You should pass the second param as string for using `arg`.
  107. ```jsx
  108. <input v-model={val} />
  109. ```
  110. ```jsx
  111. <input v-model:argument={val} />
  112. ```
  113. ```jsx
  114. <input v-model={[val, ['modifier']]} />
  115. // Or
  116. <input v-model_modifier={val} />
  117. ```
  118. ```jsx
  119. <A v-model={[val, 'argument', ['modifier']]} />
  120. // Or
  121. <input v-model:argument_modifier={val} />
  122. ```
  123. Will compile to:
  124. ```js
  125. h(A, {
  126. argument: val,
  127. argumentModifiers: {
  128. modifier: true,
  129. },
  130. 'onUpdate:argument': ($event) => (val = $event),
  131. });
  132. ```
  133. #### v-models (Not recommended since v1.1.0)
  134. > Note: You should pass a Two-dimensional Arrays to v-models.
  135. ```jsx
  136. <A v-models={[[foo], [bar, 'bar']]} />
  137. ```
  138. ```jsx
  139. <A
  140. v-models={[
  141. [foo, 'foo'],
  142. [bar, 'bar'],
  143. ]}
  144. />
  145. ```
  146. ```jsx
  147. <A
  148. v-models={[
  149. [foo, ['modifier']],
  150. [bar, 'bar', ['modifier']],
  151. ]}
  152. />
  153. ```
  154. Will compile to:
  155. ```js
  156. h(A, {
  157. modelValue: foo,
  158. modelModifiers: {
  159. modifier: true,
  160. },
  161. 'onUpdate:modelValue': ($event) => (foo = $event),
  162. bar: bar,
  163. barModifiers: {
  164. modifier: true,
  165. },
  166. 'onUpdate:bar': ($event) => (bar = $event),
  167. });
  168. ```
  169. #### custom directive
  170. Recommended when using string arguments
  171. ```jsx
  172. const App = {
  173. directives: { custom: customDirective },
  174. setup() {
  175. return () => <a v-custom:arg={val} />;
  176. },
  177. };
  178. ```
  179. ```jsx
  180. const App = {
  181. directives: { custom: customDirective },
  182. setup() {
  183. return () => <a v-custom={[val, 'arg', ['a', 'b']]} />;
  184. },
  185. };
  186. ```
  187. ### Slot
  188. > Note: In `jsx`, _`v-slot`_ should be replaced with **`v-slots`**
  189. ```jsx
  190. const A = (props, { slots }) => (
  191. <>
  192. <h1>{slots.default ? slots.default() : 'foo'}</h1>
  193. <h2>{slots.bar?.()}</h2>
  194. </>
  195. );
  196. const App = {
  197. setup() {
  198. const slots = {
  199. bar: () => <span>B</span>,
  200. };
  201. return () => (
  202. <A v-slots={slots}>
  203. <div>A</div>
  204. </A>
  205. );
  206. },
  207. };
  208. // or
  209. const App = {
  210. setup() {
  211. const slots = {
  212. default: () => <div>A</div>,
  213. bar: () => <span>B</span>,
  214. };
  215. return () => <A v-slots={slots} />;
  216. },
  217. };
  218. // or you can use object slots when `enableObjectSlots` is not false.
  219. const App = {
  220. setup() {
  221. return () => (
  222. <>
  223. <A>
  224. {{
  225. default: () => <div>A</div>,
  226. bar: () => <span>B</span>,
  227. }}
  228. </A>
  229. <B>{() => 'foo'}</B>
  230. </>
  231. );
  232. },
  233. };
  234. ```
  235. ### In TypeScript
  236. `tsconfig.json`:
  237. ```json
  238. {
  239. "compilerOptions": {
  240. "jsx": "preserve"
  241. }
  242. }
  243. ```
  244. ## Who is using
  245. <table>
  246. <tbody>
  247. <tr>
  248. <td align="center">
  249. <a target="_blank" href="https://www.antdv.com/">
  250. <img
  251. width="32"
  252. src="https://github.com/vuejs/babel-plugin-jsx/assets/6481596/8d604d42-fe5f-4450-af87-97999537cd21"
  253. />
  254. <br>
  255. <strong>Ant Design Vue</strong>
  256. </a>
  257. </td>
  258. <td align="center">
  259. <a target="_blank" href="https://youzan.github.io/vant/#/zh-CN/">
  260. <img
  261. width="32"
  262. style="vertical-align: -0.32em; margin-right: 8px;"
  263. src="https://img.yzcdn.cn/vant/logo.png"
  264. />
  265. <br>
  266. <strong>Vant</strong>
  267. </a>
  268. </td>
  269. <td align="center">
  270. <a target="_blank" href="https://github.com/element-plus/element-plus">
  271. <img
  272. height="32"
  273. style="vertical-align: -0.32em; margin-right: 8px;"
  274. src="https://user-images.githubusercontent.com/10731096/91267529-259f3680-e7a6-11ea-9a60-3286f750de01.png"
  275. />
  276. <br>
  277. <strong>Element Plus</strong>
  278. </a>
  279. </td>
  280. <td align="center">
  281. <a target="_blank" href="https://github.com/leezng/vue-json-pretty">
  282. <img
  283. height="32"
  284. style="vertical-align: -0.32em; margin-right: 8px;"
  285. src="https://raw.githubusercontent.com/leezng/vue-json-pretty/master/static/logo.svg"
  286. />
  287. <br>
  288. <strong>Vue Json Pretty</strong>
  289. </a>
  290. </td>
  291. </tr>
  292. </tbody>
  293. </table>
  294. ## Compatibility
  295. This repo is only compatible with:
  296. - **Babel 7+**
  297. - **Vue 3+**