{"id":13509055,"url":"https://github.com/vuejs/babel-plugin-transform-vue-jsx","last_synced_at":"2025-05-14T08:07:21.964Z","repository":{"id":9254147,"uuid":"61406464","full_name":"vuejs/babel-plugin-transform-vue-jsx","owner":"vuejs","description":"babel plugin for vue 2.0 jsx","archived":false,"fork":false,"pushed_at":"2022-12-06T19:46:31.000Z","size":681,"stargazers_count":1852,"open_issues_count":54,"forks_count":133,"subscribers_count":42,"default_branch":"master","last_synced_at":"2025-05-08T15:03:28.418Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vuejs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-17T22:47:17.000Z","updated_at":"2025-05-04T18:24:39.000Z","dependencies_parsed_at":"2023-01-13T15:30:14.315Z","dependency_job_id":null,"html_url":"https://github.com/vuejs/babel-plugin-transform-vue-jsx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fbabel-plugin-transform-vue-jsx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fbabel-plugin-transform-vue-jsx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fbabel-plugin-transform-vue-jsx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fbabel-plugin-transform-vue-jsx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vuejs","download_url":"https://codeload.github.com/vuejs/babel-plugin-transform-vue-jsx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253969794,"owners_count":21992350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:01:02.371Z","updated_at":"2025-05-14T08:07:21.846Z","avatar_url":"https://github.com/vuejs.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Vue","Libraries and Plugins"],"sub_categories":["PostCSS","Other"],"readme":"# babel-plugin-transform-vue-jsx [![CircleCI](https://img.shields.io/circleci/project/vuejs/babel-plugin-transform-vue-jsx.svg?maxAge=2592000)](https://circleci.com/gh/vuejs/babel-plugin-transform-vue-jsx)\n\n\u003e Babel plugin for Vue 2.0 JSX\n\n### Babel Compatibility Notes\n\n- If using Babel 7, use 4.x\n- If using Babel 6, use 3.x\n\n### Requirements\n\n- Assumes you are using Babel with a module bundler e.g. Webpack, because the spread merge helper is imported as a module to avoid duplication.\n\n- This is mutually exclusive with `babel-plugin-transform-react-jsx`.\n\n### Usage\n\n``` bash\nnpm install\\\n  babel-plugin-syntax-jsx\\\n  babel-plugin-transform-vue-jsx\\\n  babel-helper-vue-jsx-merge-props\\\n  babel-preset-env\\\n  --save-dev\n```\n\nIn your `.babelrc`:\n\n``` json\n{\n  \"presets\": [\"env\"],\n  \"plugins\": [\"transform-vue-jsx\"]\n}\n```\n\nThe plugin transpiles the following JSX:\n\n``` jsx\n\u003cdiv id=\"foo\"\u003e{this.text}\u003c/div\u003e\n```\n\nTo the following JavaScript:\n\n``` js\nh('div', {\n  attrs: {\n    id: 'foo'\n  }\n}, [this.text])\n```\n\nNote the `h` function, which is a shorthand for a Vue instance's `$createElement` method, must be in the scope where the JSX is. Since this method is passed to component render functions as the first argument, in most cases you'd do this:\n\n``` js\nVue.component('jsx-example', {\n  render (h) { // \u003c-- h must be in scope\n    return \u003cdiv id=\"foo\"\u003ebar\u003c/div\u003e\n  }\n})\n```\n\n### `h` auto-injection\n\nStarting with version 3.4.0 we automatically inject `const h = this.$createElement` in any method and getter (not functions or arrow functions) declared in ES2015 syntax that has JSX so you can drop the `(h)` parameter.\n\n``` js\n\nVue.component('jsx-example', {\n  render () { // h will be injected\n    return \u003cdiv id=\"foo\"\u003ebar\u003c/div\u003e\n  },\n  myMethod: function () { // h will not be injected\n    return \u003cdiv id=\"foo\"\u003ebar\u003c/div\u003e\n  },\n  someOtherMethod: () =\u003e { // h will not be injected\n    return \u003cdiv id=\"foo\"\u003ebar\u003c/div\u003e\n  }\n})\n\n@Component\nclass App extends Vue {\n  get computed () { // h will be injected\n    return \u003cdiv id=\"foo\"\u003ebar\u003c/div\u003e\n  }\n}\n```\n\n### Difference from React JSX\n\nFirst, Vue 2.0's vnode format is different from React's. The second argument to the `createElement` call is a \"data object\" that accepts nested objects. Each nested object will be then processed by corresponding modules:\n\n``` js\nrender (h) {\n  return h('div', {\n    // Component props\n    props: {\n      msg: 'hi',\n      onCustomEvent: this.customEventHandler\n    },\n    // normal HTML attributes\n    attrs: {\n      id: 'foo'\n    },\n    // DOM props\n    domProps: {\n      innerHTML: 'bar'\n    },\n    // Event handlers are nested under \"on\", though\n    // modifiers such as in v-on:keyup.enter are not\n    // supported. You'll have to manually check the\n    // keyCode in the handler instead.\n    on: {\n      click: this.clickHandler\n    },\n    // For components only. Allows you to listen to\n    // native events, rather than events emitted from\n    // the component using vm.$emit.\n    nativeOn: {\n      click: this.nativeClickHandler\n    },\n    // class is a special module, same API as `v-bind:class`\n    class: {\n      foo: true,\n      bar: false\n    },\n    // style is also same as `v-bind:style`\n    style: {\n      color: 'red',\n      fontSize: '14px'\n    },\n    // other special top-level properties\n    key: 'key',\n    ref: 'ref',\n    // assign the `ref` is used on elements/components with v-for\n    refInFor: true,\n    slot: 'slot'\n  })\n}\n```\n\nThe equivalent of the above in Vue 2.0 JSX is:\n\n``` jsx\nrender (h) {\n  return (\n    \u003cdiv\n      // normal attributes or prefix with on props.\n      id=\"foo\"\n      propsOnCustomEvent={this.customEventHandler}\n      // DOM properties are prefixed with `domProps`\n      domPropsInnerHTML=\"bar\"\n      // event listeners are prefixed with `on` or `nativeOn`\n      onClick={this.clickHandler}\n      nativeOnClick={this.nativeClickHandler}\n      // other special top-level properties\n      class={{ foo: true, bar: false }}\n      style={{ color: 'red', fontSize: '14px' }}\n      key=\"key\"\n      ref=\"ref\"\n      // assign the `ref` is used on elements/components with v-for\n      refInFor\n      slot=\"slot\"\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n### Component Tip\n\nIf a custom element starts with lowercase, it will be treated as a string id and used to lookup a registered component. If it starts with uppercase, it will be treated as an identifier, which allows you to do:\n\n``` js\nimport Todo from './Todo.js'\n\nexport default {\n  render (h) {\n    return \u003cTodo/\u003e // no need to register Todo via components option\n  }\n}\n```\n\n### JSX Spread\n\nJSX spread is supported, and this plugin will intelligently merge nested data properties. For example:\n\n``` jsx\nconst data = {\n  class: ['b', 'c']\n}\nconst vnode = \u003cdiv class=\"a\" {...data}/\u003e\n```\n\nThe merged data will be:\n\n``` js\n{ class: ['a', 'b', 'c'] }\n```\n\n### Vue directives\n\nNote that almost all built-in Vue directives are not supported when using JSX, the sole exception being `v-show`, which can be used with the `v-show={value}` syntax. In most cases there are obvious programmatic equivalents, for example `v-if` is just a ternary expression, and `v-for` is just an `array.map()` expression, etc.\n\nFor custom directives, you can use the `v-name={value}` syntax. However, note that directive arguments and modifiers are not supported using this syntax. There are two workarounds:\n\n1. Pass everything as an object via `value`, e.g. `v-name={{ value, modifier: true }}`\n\n2. Use the raw vnode directive data format:\n\n``` js\nconst directives = [\n  { name: 'my-dir', value: 123, modifiers: { abc: true } }\n]\n\nreturn \u003cdiv {...{ directives }}/\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvuejs%2Fbabel-plugin-transform-vue-jsx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvuejs%2Fbabel-plugin-transform-vue-jsx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvuejs%2Fbabel-plugin-transform-vue-jsx/lists"}