Vue:不能在 TSX 中使用渲染道具
Vue: can't use render props with TSX
在我的设置中,在 vue 组件中编写的 jsx 工作正常,然后我在 TS 上迁移项目并使用 vue-class-component
。
对我来说,唯一适用于 tsx 的是以下内容(如 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>
}
}
注意这里的 h
- 没有它 - 它不起作用,但是 should
我有一个可以接受渲染道具的组件。看起来像这样:
// this is js component, so works even without `h` added manually
render() {
return (
<td>
{this.$props.render
? this.$props.render(this)
: this.defaultRender(this)}
</td>
)
}
默认渲染一些其他的jsx。并且默认工作正常。但是当我尝试使用 jsx 传递函数时,它不起作用(在 TSX 中,对于常见的基于 vue js 的组件,它工作完美)。
我曾经将这个 jsx 写在我创建的钩子中。像这样:
created() {
this.columns = [
{
field: 'fieldWithCustomRenderFn',
label: 'Some name',
renderCell: ({ row }) => (
<div onClick={() => this.someHandler(row)}>
{row.someData}
</div>
)
}
]
}
请注意,我不必以某种方式在这里传递 h
。它适用于 JS - 但不适用于 TSX。不知道为什么...
转译后如下所示:
renderCell: function renderCell(_a) {
var row = _a.row
return h('a', {
on: {
'click': function click(e) {
_this.someHandler(row)
}
}
}, [row.someData])
}
的确是jsx被改造了,但是h
这里是undefined。我看到了来自 js 的转译代码(有效),对我来说主要区别在于那一行:
var h = this.$createElement;
在 created() 函数中。我在 tsx 组件的转译代码中没有看到这一行。我在这里做错了什么?
这是我的.babelrc(我用的是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"
],
和 webpack 规则
{
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)
)
},
看起来像 known issue 带有 babel-plugin-transform-vue-jsx。我只是通过使用 jsx:
在我的函数中手动添加这个字符串来解决这个问题
const h = this.$createElement;
从编译和运行的角度来看,它可以正常工作。不过当然只是个拐杖。
在我的设置中,在 vue 组件中编写的 jsx 工作正常,然后我在 TS 上迁移项目并使用 vue-class-component
。
对我来说,唯一适用于 tsx 的是以下内容(如 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>
}
}
注意这里的 h
- 没有它 - 它不起作用,但是 should
我有一个可以接受渲染道具的组件。看起来像这样:
// this is js component, so works even without `h` added manually
render() {
return (
<td>
{this.$props.render
? this.$props.render(this)
: this.defaultRender(this)}
</td>
)
}
默认渲染一些其他的jsx。并且默认工作正常。但是当我尝试使用 jsx 传递函数时,它不起作用(在 TSX 中,对于常见的基于 vue js 的组件,它工作完美)。
我曾经将这个 jsx 写在我创建的钩子中。像这样:
created() {
this.columns = [
{
field: 'fieldWithCustomRenderFn',
label: 'Some name',
renderCell: ({ row }) => (
<div onClick={() => this.someHandler(row)}>
{row.someData}
</div>
)
}
]
}
请注意,我不必以某种方式在这里传递 h
。它适用于 JS - 但不适用于 TSX。不知道为什么...
转译后如下所示:
renderCell: function renderCell(_a) {
var row = _a.row
return h('a', {
on: {
'click': function click(e) {
_this.someHandler(row)
}
}
}, [row.someData])
}
的确是jsx被改造了,但是h
这里是undefined。我看到了来自 js 的转译代码(有效),对我来说主要区别在于那一行:
var h = this.$createElement;
在 created() 函数中。我在 tsx 组件的转译代码中没有看到这一行。我在这里做错了什么?
这是我的.babelrc(我用的是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"
],
和 webpack 规则
{
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)
)
},
看起来像 known issue 带有 babel-plugin-transform-vue-jsx。我只是通过使用 jsx:
在我的函数中手动添加这个字符串来解决这个问题const h = this.$createElement;
从编译和运行的角度来看,它可以正常工作。不过当然只是个拐杖。