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;

从编译和运行的角度来看,它可以正常工作。不过当然只是个拐杖。