使用 JSX 包从基本 CLI 安装中获取 Vue.js 以使用 TypeScript 呈现 JSX [英] Getting Vue.js to render JSX with TypeScript from base CLI install with JSX package
问题描述
我已经使用vue-创建了一个基本项目-cli,在此期间我使用了手动选择功能";安装,我选择了以下内容(除了 linter):
I've created a basic project with the vue-cli, during which I used the "Manually select features" to install, where I picked the following (besides a linter):
- 选定 Babel、TypeScript、Vuex 和 Linter/Formatter
- 已选择 2.x
- 没有类样式的组件
- 是将 Babel 与 TypeScript 一起使用(现代模式需要,自动检测的 polyfill,转译 JSX)?
- Selected Babel, TypeScript, Vuex, and Linter / Formatter
- Selected 2.x
- No to class-style components
- Yes to Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)?
然后,我还安装了jsx support(我验证安装的 Babel 版本是 7,因为那是该 jsx 支持 repo 所必需的).
Then afterwards, I also installed the jsx support (and I verified the Babel version installed was 7, since that is required for that jsx support repo).
在我的 bable.config.js 文件中,我添加(没有替换 vue-cli 生成的内容)jsx repo 请求的预设:>
In my bable.config.js file I added (did not replace what was generated by the vue-cli) the preset requested by the jsx repo:
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
'@vue/babel-preset-jsx', //<-- Added this
],
};
我已确认自动生成 tsconfig.json 具有所需的配置(至少据我所知):
I've confirmed that the auto-generated tsconfig.json has the needed configuration (at least as I understand it):
"compilerOptions": {
...
"jsx": "preserve",
...
}
我已确认自动生成 shims-tsx.d.ts 文件具有所需的配置(至少据我所知):
I've confirmed that the auto-generated shims-tsx.d.ts file has the needed configuration (at least as I understand it):
import Vue, { VNode } from 'vue';
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any
}
}
}
在生成的自动生成 main.ts 文件中,JSX 似乎已成功使用(即使它不是 .tsx
扩展,我相信 webpack,在幕后,正在改变事情的工作:
In the resulting auto-generated main.ts file, the JSX appears to be successfully used (even though it is not a .tsx
extension, as I believe webpack, behind the scenes, is transforming things to work:
new Vue({
store,
render: (h) => h(App),
}).$mount('#app');
所以自动生成的 App.vue 文件有这个(我忽略了 信息),它呈现良好 在
npm run serve
上:
So the auto-generated App.vue file has this (I'm ignoring the <style>
info), which renders fine on npm run serve
:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</div>
</template>
<script lang="ts">
import Vue, {VNode} from 'vue';
import HelloWorld from './components/HelloWorld.vue';
export default Vue.extend({
name: 'App',
components: {
HelloWorld,
},
});
</script>
</模板><script lang="ts">从 'vue' 导入 Vue,{VNode};从 './components/HelloWorld.vue' 导入 HelloWorld;导出默认 Vue.extend({name: '应用程序',成分: {你好,世界,},});
The Issues
It is my understanding that the following modification to App.vue should then work (the render function is exactly what the first "Syntax" example in the jsx repo has):
问题
据我所知,对 App.vue 的以下修改应该可以工作(渲染函数正是 jsx 存储库中第一个语法"示例所具有的):
// template removed
<script lang="ts">
import Vue, {VNode} from 'vue';
import HelloWorld from './components/HelloWorld.vue';
export default Vue.extend({
name: 'App',
functional: true,
render() {
return <p>hello</p>
}
});
</script>
But instead, I get this set of errors in the terminal window:
但相反,我在终端窗口中收到了这组错误:
ERROR in /home/scott/convrrt-component/view-play/src/App.vue(19,3):
19:3 No overload matches this call.
The last overload gave the following error.
Type '() => boolean' is not assignable to type '(createElement: CreateElement, hack: RenderContext<Record<string, any>>) => VNode'.
Type 'boolean' is not assignable to type 'VNode'.
17 | HelloWorld,
18 | },*/
> 19 | render() {
| ^
20 | return <p>hello</p>
21 | }
22 | });
ERROR in /home/scott/convrrt-component/view-play/src/App.vue(20,13):
20:13 Cannot find name 'p'.
18 | },*/
19 | render() {
> 20 | return <p>hello</p>
| ^
21 | }
22 | });
23 | </script>
ERROR in /home/scott/convrrt-component/view-play/src/App.vue(20,15):
20:15 Cannot find name 'hello'.
18 | },*/
19 | render() {
> 20 | return <p>hello</p>
| ^
21 | }
22 | });
23 | </script>
Version: typescript 4.1.6
I thought maybe I needed to explicitly use the h()
function, so I tried this for the render
function (sort of matching to what the main.ts
was doing):
我想也许我需要显式使用 h()
函数,所以我为 render
函数尝试了这个(有点匹配 main.ts
正在做):
render(h, ctx) {
return h(<p>hello</p>)
}
That did not work. The last two errors are the same as above, but the first error changes to this:
那没用.最后两个错误和上面一样,但是第一个错误变成了这样:
ERROR in /home/scott/convrrt-component/view-play/src/App.vue(20,14):
20:14 No overload matches this call.
Overload 1 of 2, '(tag?: string | VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...> | (() => Component<...>) | undefined, children?: VNodeChildren): VNode', gave the following error.
Argument of type 'boolean' is not assignable to parameter of type 'string | VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...> | (() => Component<...>) | undefined'.
Overload 2 of 2, '(tag?: string | VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...> | (() => Component<...>) | undefined, data?: VNodeData | undefined, children?: VNodeChildren): VNode', gave the following error.
Argument of type 'boolean' is not assignable to parameter of type 'string | VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...> | (() => Component<...>) | undefined'.
18 | },*/
19 | render(h, ctx) {
> 20 | return h(<p>hello</p>)
| ^
21 | }
22 | });
23 | </script>
I've tried a few other things that I cannot quite recall now (explicit typing on the render
was one, I think, both on the function itself and on the return value).
我已经尝试了一些我现在不太记得的其他事情(我认为在 render
上的显式输入是一种,无论是在函数本身还是在返回值上).>
问题:我仍然缺少什么设置/配置,或者我有什么语法问题导致仍然无法将 return
呈现为 JSX 并通过 TypeScript 挑战?
Question: What setup/configuration am I still missing or what syntax issue do I have that is causing this to still fail to render the return
as JSX and pass the TypeScript gauntlet?
推荐答案
JSX 默认开启
您无需在 Vue CLI 脚手架项目中为 JSX 支持安装任何东西.@vue/cli-plugin-babel/preset
包含 @vue/babel-preset-app
,它已经 包括@vue/babel-preset-jsx
.
将 '@vue/babel-preset-jsx'
附加到 Babel 预设会引入错误(可能是由于默认情况下已经存在的预设设置重复).你应该删除它:
Appending '@vue/babel-preset-jsx'
to the Babel presets introduces errors (likely due to duplication of preset settings already in place by default). You should remove that:
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
// '@vue/babel-preset-jsx', // XXX: Remove this
],
};
VS 代码扩展警告
如果使用 Vetur 或 VueDX 在 VS Code 中,您会注意到 JSX 行上报告的 TypeScript 错误.使用 来避免这些错误:
VS Code Extensions caveat
If using Vetur or VueDX in VS Code, you'll notice TypeScript errors reported on the JSX lines. Use <script lang="tsx">
to avoid these errors:
<script lang="tsx">
import Vue from 'vue'
export default Vue.extend({
render() {
return <b>hello</b>
}
})
</script>
这篇关于使用 JSX 包从基本 CLI 安装中获取 Vue.js 以使用 TypeScript 呈现 JSX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!