vue3—TSX

本文介绍了如何在Vite项目中安装和配置TSX,包括修改vite.config.ts和tsconfig.json文件,以及如何使用TSX进行v-model、v-show等Vue指令的替代方法。同时,提到了vite-plugin-tsx插件的实现,用于解析tsx文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TSX

安装

npm install @vitejs/plugin-vue-jsx -D

1、vite.config.ts 配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6wWk5nr-1679501159916)(C:\Users\huawei\AppData\Roaming\Typora\typora-user-images\image-20230321225756655.png)]

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

2、修改tsconfig.json 配置文件

    "jsx": "preserve",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment",

3、使用TSX

 import { ref } from 'vue'
 
let v = ref<string>('')
 
const renderDom = () => {
    return (
        <>
           <input v-model={v.value} type="text" />
           <div>
               {v.value}
           </div>
        </>
    )
}
 
export default renderDom
3.1.v-model
import { ref } from 'vue'
 
let v = ref<string>('')
 
const renderDom = () => {
    return (
        <>
           <input v-model={v.value} type="text" />
           <div>
               {v.value}
           </div>
        </>
    )
}
 
export default renderDom
3.2.v-show
import { ref } from 'vue'
 
let flag = ref(false)
 
const renderDom = () => {
    return (
        <>
           <div v-show={flag.value}>景天</div>
           <div v-show={!flag.value}>雪见</div>
        </>
    )
}
 
export default renderDom
3.3.v-if是不支持的
import { ref } from 'vue'
 
let flag = ref(false)
 
const renderDom = () => {
    return (
        <>
            {
                flag.value ? <div>景天</div> : <div>雪见</div>
            }
        </>
    )
}
 
export default renderDom
3.4.v-for也不支持
import { ref } from 'vue'
 
let arr = [1,2,3,4,5]
 
const renderDom = () => {
    return (
        <>
            {
              arr.map(v=>{
                  return <div>${v}</div>
              })
            }
        </>
    )
}
 
export default renderDom
3.5.v-bind
import { ref } from 'vue'
 
let arr = [1, 2, 3, 4, 5]
 
const renderDom = () => {
    return (
        <>
            <div data-arr={arr}>1</div>
        </>
    )
}
 
export default renderDom
3.6.v-on绑定事件 所有的事件都按照react风格来
  • 所有事件有on开头
  • 所有事件名称首字母大写
const renderDom = () => {
    return (
        <>
            <button onClick={clickTap}>点击</button>
        </>
    )
}
 
const clickTap = () => {
    console.log('click');
}
 
export default renderDom
3.7.Props 接受值
import { ref } from 'vue'
 
type Props = {
    title:string
}
 
const renderDom = (props:Props) => {
    return (
        <>
            <div>{props.title}</div>
            <button onClick={clickTap}>点击</button>
        </>
    )
}
 
const clickTap = () => {
    console.log('click');
}
 
export default renderDom
3.8.Emit派发
type Props = {
    title: string
}
 
const renderDom = (props: Props,content:any) => {
    return (
        <>
            <div>{props.title}</div>
            <button onClick={clickTap.bind(this,content)}>点击</button>
        </>
    )
}
 
const clickTap = (ctx:any) => {
 
    ctx.emit('on-click',1)
}
3.9.Slot
const A = (props, { slots }) => (
  <>
    <h1>{ slots.default ? slots.default() : 'foo' }</h1>
    <h2>{ slots.bar?.() }</h2>
  </>
);
 
const App = {
  setup() {
    const slots = {
      bar: () => <span>B</span>,
    };
    return () => (
      <A v-slots={slots}>
        <div>A</div>
      </A>
    );
  },
};
 
// or
 
const App = {
  setup() {
    const slots = {
      default: () => <div>A</div>,
      bar: () => <span>B</span>,
    };
    return () => <A v-slots={slots} />;
  },
};
 
// or you can use object slots when `enableObjectSlots` is not false.
const App = {
  setup() {
    return () => (
      <>
        <A>
          {{
            default: () => <div>A</div>,
            bar: () => <span>B</span>,
          }}
        </A>
        <B>{() => "foo"}</B>
      </>
    );
  },
};
附:实现一个vite插件解析tsx

第三方插件

npm install @vue/babel-plugin-jsx
npm install @babel/core
npm install @babel/plugin-transform-typescript
npm install @babel/plugin-syntax-import-meta
npm install @types/babel__core

插件代码

import type { Plugin } from 'vite'
import * as babel from '@babel/core'; //@babel/core核心功能:将源代码转成目标代码。
import jsx from '@vue/babel-plugin-jsx'; //Vue给babel写的插件支持tsx v-model等
export default function (): Plugin {
    return {
        name: "vite-plugin-tsx",
        config (config) {
           return {
              esbuild:{
                 include:/\.ts$/
              }
           }
        },
        async transform(code, id) {
            if (/.tsx$/.test(id)) {
                //@ts-ignore
                const ts = await import('@babel/plugin-transform-typescript').then(r=>r.default)
                const res = babel.transformSync(code,{
                    plugins:[jsx,[ts, { isTSX: true, allowExtensions: true }]], //添加babel插件
                    ast:true, // ast: 抽象语法树,源代码语法结构的一种抽象表示。babel内部就是通过操纵ast做到语法转换。
                    babelrc:false, //.babelrc.json
                    configFile:false //默认搜索默认babel.config.json文件
                })
                return res?.code //code: 编译后的代码
            }
           
            return code
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kBieooQp-1679501159919)(C:\Users\huawei\AppData\Roaming\Typora\typora-user-images\image-20230321231258033.png)]

在这里插入图片描述

### 解决 `fileURLToPath` 方法从 `node:url` 导入时报错的问题 当遇到 `Error: Cannot find module &#39;node:url&#39;` 的错误时,这通常是因为 Node.js 版本过低或项目配置存在问题。以下是详细的解决方案: #### 1. 升级 Node.js 版本 确保使用的 Node.js 版本支持 ES 模块和 `node:url` 模块。建议升级到 LTS 或更高版本。 ```bash nvm install --lts nvm use --lts ``` #### 2. 修改 package.json 文件 如果使用的是 Vite 构建工具,默认情况下会启用 ESM (ECMAScript Modules),因此需要确保 `package.json` 中有 `"type": "module"` 字段。 ```json { "name": "your-project", "version": "1.0.0", "private": true, "type": "module", // 添加此字段 ... } ``` #### 3. 安装缺失模块 有时可能缺少必要的依赖项,尝试重新安装所有依赖包并清理缓存。 ```bash rm -rf node_modules npm cache clean --force npm install ``` #### 4. 使用兼容语法引入 `url` 模块 对于某些环境来说,直接通过 `import { fileURLToPath } from &#39;url&#39;;` 可能不被识别。可以改为如下方式来加载该功能[^1]。 ```javascript // CommonJS 风格写法适用于更广泛的场景 const { fileURLToPath } = require(&#39;url&#39;); ``` 或者采用动态导入的方式: ```javascript (async () => { const urlModule = await import(&#39;url&#39;); const { fileURLToPath } = urlModule; })(); ``` 以上措施应该能够有效解决因找不到 `node:url` 而引发的各种报错情况。另外需要注意检查其他地方是否存在类似的路径解析逻辑,必要时也应做相应调整以保持一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值