Vue 使用 JSX 开发配置
HumphreyDanvue3 使用 ts 开发,天然支持 tsx 开发.本文记录下如何在 bun + vitejs 环境下配置 tsx
1、添加依赖
1 2
| bun add vue vue-router vuetify bun add -D @mdi/font @types/node @vitejs/plugin-vue @vitejs/plugin-vue-jsx typescript vite vue-tsc
|
2、配置 tsconfig.json
主要是打开 jsx 支持
1 2 3 4
| { "jsx": "preserve", "jsxImportSource": "vue", }
|
完整配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": [ "ES2020", "DOM", "DOM.Iterable" ], "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "jsx": "preserve", "jsxImportSource": "vue", "paths": { "@/*": [ "./src/*" ], "~/*": [ "./public/*" ] } }, "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "vite.config.ts", ] }
|
3、配置 vite.config.ts
1 2 3 4
| ++ import vue from "@vitejs/plugin-vue"; ++ import vueJsx from '@vitejs/plugin-vue-jsx' export default defineConfig(async () => ({ ++ plugins: [vue(), vueJsx())],
|
如此就可以直接使用 tsx 文件进行开发.
4、由于 vscode 插件对 tsx 支持不完善, 导致 onClick 等事件识别不了而报 lint 错误,所以手动添加下类型说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| import { VNodeProps } from 'vue'
type EventModifiers = { capture?: boolean once?: boolean passive?: boolean stop?: boolean prevent?: boolean self?: boolean }
type EventHandler<T = Event> = ((event: T) => void) | { handler: (event: T) => void modifiers: EventModifiers }
export type ModifierKey = 'stop' | 'prevent' | 'capture' | 'self' | 'once' | 'passive'
export type WithModifiers<T> = T & { [key in `_${ModifierKey}`]: WithModifiers<T> }
export type EventHandlerWithModifiers<T extends Function> = WithModifiers<T>
declare module 'vue' { interface HTMLAttributes { onClick?: EventHandler<MouseEvent> onDblclick?: EventHandler<MouseEvent> onMousedown?: EventHandler<MouseEvent> onMouseup?: EventHandler<MouseEvent> onMouseover?: EventHandler<MouseEvent> onMousemove?: EventHandler<MouseEvent> onMouseout?: EventHandler<MouseEvent> onContextmenu?: EventHandler<MouseEvent>
onKeydown?: EventHandler<KeyboardEvent> onKeypress?: EventHandler<KeyboardEvent> onKeyup?: EventHandler<KeyboardEvent>
onChange?: EventHandler<Event> onInput?: EventHandler<Event> onSubmit?: EventHandler<Event> onReset?: EventHandler<Event>
onFocus?: EventHandler<FocusEvent> onBlur?: EventHandler<FocusEvent>
onScroll?: EventHandler<UIEvent> onWheel?: EventHandler<WheelEvent> onDrag?: EventHandler<DragEvent> onDragstart?: EventHandler<DragEvent> onDragend?: EventHandler<DragEvent> onDragenter?: EventHandler<DragEvent> onDragleave?: EventHandler<DragEvent> onDragover?: EventHandler<DragEvent> onDrop?: EventHandler<DragEvent> }
interface ComponentCustomProps extends HTMLAttributes { [event: `on${string}`]: (...args: any[]) => void } }
|
另外如果想在项目中使用 mdx, 需要如下配置
1、添加依赖
1 2
| bun add @mdx-js/vue bun add -D @mdx-js/rollup @mdx-js/vue @types/mdx
|
2、配置 vite.config.ts
1 2 3 4 5 6 7 8 9 10 11
| ++ import mdx from '@mdx-js/rollup' export default defineConfig(async () => ({ plugins: [vue(), vueJsx(), ++ mdx({ ++ jsxImportSource: 'vue', ++ jsxRuntime: 'automatic', // 或 'automatic' ++ providerImportSource: '@mdx-js/vue', // 使用 Vue 运行时 ++ remarkPlugins: [], ++ rehypePlugins: [] }) ],
|
主要配置 mdx 插件,使用 @mdx-js/vue
来渲染生成 mdx 文件对应的 VNode. 否则就会使用内置的 preact
生成 Component 而报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import vueJsx from '@vitejs/plugin-vue-jsx' import mdx from '@mdx-js/rollup' import path from "path" const host = process.env.TAURI_DEV_HOST;
export default defineConfig(async () => ({ plugins: [vue(), vueJsx(), mdx({ jsxImportSource: 'vue', jsxRuntime: 'automatic', providerImportSource: '@mdx-js/vue', remarkPlugins: [], rehypePlugins: [] })], resolve: { alias: { "@": path.resolve(__dirname, "./src"), "~": path.resolve(__dirname, "./public"), }, }, clearScreen: false, server: { port: 1420, strictPort: true, host: host || false, hmr: host ? { protocol: "ws", host, port: 1421, } : undefined, watch: { ignored: ["**/src-tauri/**"], }, }, }));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import { defineComponent } from "vue"; import { VCard, VContainer, VSheet } from "vuetify/components"; import Earth from '~/mdx/Earth.mdx';
export default defineComponent({ setup() { return () => ( <VContainer> <VSheet rounded="lg"></VSheet> <VCard> <Earth/> </VCard> </VContainer> ) } })
|