Gathering detailed insights and metrics for babel-plugin-transform-vue-tsx
Gathering detailed insights and metrics for babel-plugin-transform-vue-tsx
Gathering detailed insights and metrics for babel-plugin-transform-vue-tsx
Gathering detailed insights and metrics for babel-plugin-transform-vue-tsx
npm install babel-plugin-transform-vue-tsx
Typescript
Module System
77.4
Supply Chain
99.3
Quality
74.9
Maintenance
100
Vulnerability
100
License
JavaScript (99.42%)
HTML (0.58%)
Total Downloads
579,373
Last Day
338
Last Week
3,454
Last Month
11,187
Last Year
126,492
1,851 Stars
84 Commits
132 Forks
42 Watchers
15 Branches
86 Contributors
Updated on May 29, 2025
Minified
Minified + Gzipped
Latest Version
3510.0.3
Package Id
babel-plugin-transform-vue-tsx@3510.0.3
Unpacked Size
51.90 kB
Size
14.45 kB
File Count
10
Cumulative downloads
Total Downloads
Last Day
-26%
338
Compared to previous day
Last Week
-23.6%
3,454
Compared to previous week
Last Month
33.4%
11,187
Compared to previous month
Last Year
-47.5%
126,492
Compared to previous year
此插件基于babel-plugin-transform-vue-jsx修改,解决 TSX 语法严格类型下的一些问题:
对于 tsx, 标签的类型是限定的,为了支持其他类库的自定义组件正常使用,在vue-tsx-helper库中提供了 anyslot 标签,包含必须属性 is,其值为目标组件 id
例如在 TSX 中添加一个 vue-router link
使用<RouterLink></RouterLink>
会报类型错误,但 TypeScript 认为固有标签应该全部是小写,因此也无法定义 RouterLink
的 type
使用<router-link></router-link>
不适合 TSX 语法,因为不允许-字符
因此可以使用如下
1import { Component, Prop } from "vue-property-decorator"; 2import { VueComponent } from "vue-tsx-helper"; // 同时全局提供了anyslot的类型定义 3import TestComponent from "../TestComponent"; 4 5/** 6 * Vue component props types 7 */ 8interface IProps {} 9 10@Component 11export default class WrapTestComponent extends VueComponent<IProps> { 12 @Prop() msg; 13 14 render(h) { 15 return ( 16 <TestComponent msg={"msg from parent"}> 17 <h2>Page writed without .vue but plain tsx</h2> 18 <anyslot is="router-link" to="/"> 19 Back to home 20 </anyslot> 21 </TestComponent> 22 ); 23 } 24}
Babel plugin for Vue 2.0 TSX
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.
This is mutually exclusive with babel-plugin-transform-react-jsx
.
1npm install\ 2 babel-plugin-syntax-jsx\ 3 babel-plugin-transform-vue-tsx\ 4 babel-helper-vue-jsx-merge-props\ 5 babel-preset-env\ 6 --save-dev
In your .babelrc
:
1{ 2 "presets": ["env"], 3 "plugins": ["transform-vue-tsx"] 4}
The plugin transpiles the following JSX:
1<div id="foo">{this.text}</div>
To the following JavaScript:
1h( 2 "div", 3 { 4 attrs: { 5 id: "foo" 6 } 7 }, 8 [this.text] 9);
Note 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:
1Vue.component("jsx-example", { 2 render(h) { 3 // <-- h must be in scope 4 return <div id="foo">bar</div>; 5 } 6});
h
auto-injectionStarting 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.
1Vue.component("jsx-example", { 2 render() { 3 // h will be injected 4 return <div id="foo">bar</div>; 5 }, 6 myMethod: function() { 7 // h will not be injected 8 return <div id="foo">bar</div>; 9 }, 10 someOtherMethod: () => { 11 // h will not be injected 12 return <div id="foo">bar</div>; 13 } 14}); 15 16@Component 17class App extends Vue { 18 get computed() { 19 // h will be injected 20 return <div id="foo">bar</div>; 21 } 22}
First, 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:
1render (h) { 2 return h('div', { 3 // Component props 4 props: { 5 msg: 'hi' 6 }, 7 // normal HTML attributes 8 attrs: { 9 id: 'foo' 10 }, 11 // DOM props 12 domProps: { 13 innerHTML: 'bar' 14 }, 15 // Event handlers are nested under "on", though 16 // modifiers such as in v-on:keyup.enter are not 17 // supported. You'll have to manually check the 18 // keyCode in the handler instead. 19 on: { 20 click: this.clickHandler 21 }, 22 // For components only. Allows you to listen to 23 // native events, rather than events emitted from 24 // the component using vm.$emit. 25 nativeOn: { 26 click: this.nativeClickHandler 27 }, 28 // class is a special module, same API as `v-bind:class` 29 class: { 30 foo: true, 31 bar: false 32 }, 33 // style is also same as `v-bind:style` 34 style: { 35 color: 'red', 36 fontSize: '14px' 37 }, 38 // other special top-level properties 39 key: 'key', 40 ref: 'ref', 41 // assign the `ref` is used on elements/components with v-for 42 refInFor: true, 43 slot: 'slot' 44 }) 45}
The equivalent of the above in Vue 2.0 JSX is:
1render (h) { 2 return ( 3 <div 4 // normal attributes or component props. 5 id="foo" 6 // DOM properties are prefixed with `domProps` 7 domPropsInnerHTML="bar" 8 // event listeners are prefixed with `on` or `nativeOn` 9 onClick={this.clickHandler} 10 nativeOnClick={this.nativeClickHandler} 11 // other special top-level properties 12 class={{ foo: true, bar: false }} 13 style={{ color: 'red', fontSize: '14px' }} 14 key="key" 15 ref="ref" 16 // assign the `ref` is used on elements/components with v-for 17 refInFor 18 slot="slot"> 19 </div> 20 ) 21}
If 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:
1import Todo from "./Todo.js"; 2 3export default { 4 render(h) { 5 return <Todo />; // no need to register Todo via components option 6 } 7};
JSX spread is supported, and this plugin will intelligently merge nested data properties. For example:
1const data = { 2 class: ["b", "c"] 3}; 4const vnode = <div class="a" {...data} />;
The merged data will be:
1{ class: ['a', 'b', 'c'] }
Note 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.
For 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:
Pass everything as an object via value
, e.g. v-name={{ value, modifier: true }}
Use the raw vnode directive data format:
1const directives = [{ name: "my-dir", value: 123, modifiers: { abc: true } }]; 2 3return <div {...{ directives }} />;
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
Found 12/29 approved changesets -- score normalized to 4
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
license file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
76 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-06-23
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More