After switching my setup from JSX in a Vue component to TS with vue-class-component
, I found that only the code snippet below works for me (as shown in the example on repo):
import Vue from 'vue'
import { Component } from 'vue-property-decorator'
@Component
export default class TSXTest extends Vue {
render(h) {
return <h1>It works</h1>
}
}
The key here is using h
as shown in the example, which seems necessary. Although it should be automatically injected according to this.
In a scenario where I have a component accepting render props like below:
// This is a JS component, so it works even without manually adding `h`
render() {
return (
<td>
{this.$props.render
? this.$props.render(this)
: this.defaultRender(this)}
</td>
)
}
The default rendering process works fine, but when attempting to pass a function with JSX, it fails to work in TSX, although it works perfectly for common Vue.js based components.
I used to write JSX inside the created hook like this:
created() {
this.columns = [
{
field: 'fieldWithCustomRenderFn',
label: 'Some name',
renderCell: ({ row }) => (
<div onClick={() => this.someHandler(row)}>
{row.someData}
</div>
)
}
]
}
Notably, there's no need to pass h
in the above example, and it worked in JS but not in TSX. I'm unsure why...
When transpiled, the code looks like this:
renderCell: function renderCell(_a) {
var row = _a.row
return h('a', {
on: {
'click': function click(e) {
_this.someHandler(row)
}
}
}, [row.someData])
}
Although the JSX is transformed, h
appears to be undefined here. The difference I noticed between the working JS code and TSX code is the presence of this line:
var h = this.$createElement;
inside the created() function, which is absent in the transpiled code of my TSX component. What could be the issue here?
Below are snippets from my .babelrc file (using Babel 6):
"presets": [
["env", {
"modules": "commonjs",
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 11"]
}
}],
"stage-2"
],
"plugins": [
"syntax-dynamic-import",
"transform-vue-jsx",
"transform-runtime"
],
And webpack rules:
{
test: /\.ts$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true
}
},
{
test: /\.tsx$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'ts-loader',
options: {
transpileOnly: true
}
}
]
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) && !/\.vue\.js/.test(file)
)
}