vue3无法使用jsx的问题及解决

目录
  • vue3无法使用jsx问题
    • 报错一:无法使用 JSX,除非提供了 "--jsx" 标志
    • 报错二:ElementPlusIconsVue挂载问题
  • 关于vue3的jsx写法问题
    • 安装 @vitejs/plugin-vue-jsx vite 插件
    • 编写示例

vue3无法使用jsx问题

报错一:无法使用 JSX,除非提供了 "--jsx" 标志

在Vite+Vue3.0中使用jsx语法开发,需要安装jsx插件

npm i @vitejs/plugin-vue-jsx -s

在vite.config.js加入jsx配置

// vite.config.js
import { defineConfig } from 'vite'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx()],
})

至此,我们新建的这个vite项目已经全面支持jsx语法了,此时还需要在tsconfig.ts中配置"jsx": "preserve"属性,就可以愉快的使用jsx形式来写vue了。

报错二:ElementPlusIconsVue挂载问题

import ElementPlusIconsVue

类型“typeof import("D:/\u9879\u76EE/00/model-dev-platform-doc/node_modules/@element-plus/icons-vue/dist/types/index")”的参数不能赋给类型“Plugin_2”的参数。

解决办法:

经过善良的QQ群友点拨之后才明白....

需要遍历挂载

报错二:vue3.0+ts 找不到模块“./XXX.vue”或其相应的类型声明。

鹅鹅鹅鹅鹅鹅.....还没找到原因

卸载掉volar插件,全部报错都消失

关于vue3的jsx写法问题

安装 @vitejs/plugin-vue-jsx vite 插件

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

安装完成之后,在 vite.config.js 中进行配置:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
export default defineConfig({
    plugins: [
        vue(),
        vueJsx(),
    ]
})

然后,即可编写 jsx 形式的 vue 单文件组件。

编写示例

基础实例

vue3 新增了 setup 这个组合式 api,这样就使得利用 jsx 编写 vue 组件时的风格非常类似于 react。在 setup 可以创建 state,接受 props,还可以直接返回 jsx。

import { defineComponent} from 'vue';
export default defineComponent({
    setup() {
        return <div>123456789</div>
    }
});

props 和 state

在 vue3 中,存在 ref 和 reactive 这两个创建响应式状态的 api。由于内置的观察者模式,导致 vue 并不需要像 react 那样,提供 useMemo,useCallback 等根据条件判断是否更新的钩子。

ref 在 render 函数中,会自动解构,不需要再使用 ref.value 来获取里面的值。

推荐使用 ref,而不是 reactive。

props 则需要在 defineComponent 中使用 props 属性,指定 props,该组件才会接受对应的 props。

子组件不能在 setup 中返回 jsx,否则弹出警告,不渲染该子组件。

父组件接受子组件后,不可在 setup 中直接返回 ctx,或者 ctx.slots?.default?.() 计算后的值,第一种情况弹出警告,不渲染该子组件;第二种情况,该子组件不会响应式。正确的做法,应该是返回一个渲染函数。

子组件:

import { defineComponent, ref, reactive } from 'vue;
export default defineComponent({
    name: 'TestB',
    // 必须传递props,提醒 vue,该组件可以接受名称为 str 的值
    // 如果不填,则 props 接受不到该值。
    // 如果该组件为子组件,不可在 setup 中返回元素,必须在 render 中返回元素
    props: ['str'],
    setup(this, props, ctx) {
        const count = ref(0);
        const { str } = props;
        const reactiveCount = reactive({value: 0});
        return {
            str,
            count,
            reactiveCount,
        }
    },
    render() {
        const { count, reactiveCount, str } = this;
        return <div>{count} - {reactiveCount.value} - {str}</div>
    }
});

父组件:

import { defineComponent } from "vue";
export default defineComponent({
    props: ['testStr'],
    name: 'TestA',
    setup(props, ctx) {
        const { testStr } = props;
        // 注意,不要直接返回一个 ctx.slots?.default?.() 计算后的值,这样不能响应式
        // 同时,也要注意,不能直接返回 ctx,会有警告,同时不会显示子元素
        const renderFn = () => {
            return <div>{ ctx.slots?.default?.() ?? "" }</div>
        }
        return {
            testStr,
            renderFn,
        }
    },
    render() {
        const { testStr, renderFn } = this;
        return <div>你输入的字符串: {testStr}
            <div>子组件</div>
            <div>{ renderFn() }</div>
        </div>
    }
})

事件监听

@vitejs/plugin-vue-jsx 该插件默认将 @input 等相关模板语法,替换成了 onInput 等 jsx 形式。这里以点击事件举例。

import { defineComponent, ref, reactive } from "vue";
interface ITestAProps {
  str: string;
}
export default defineComponent({
  name: "TestA",
  props: ["str"],
  setup(this, props, ctx) {
    const count = ref(0);
    const { str } = props;
    const reactiveCount = reactive({ value: 0 });
    const onClick = () => {
      count.value++;
    };
    const reactiveClick = () => {
      reactiveCount.value++;
    };
    return {
      str,
      count,
      reactiveCount,
      onClick,
      reactiveClick,
    };
  },
  render() {
    const { count, reactiveCount, str, onClick, reactiveClick } = this;
    return (
      <div>
        <div onClick={onClick}>{count}</div>
        <div onClick={reactiveClick}>{reactiveCount.value}</div>
        <div>{str}</div>
      </div>
    );
  },
});

插槽

vue3 中,可以使用快捷语法(以 element-plus 举例)

<el-popconfirm
  title="确认删除最后一个配置内容?"
  confirm-button-text="确认"
  cancel-button-text="取消"
  @confirm="
      addNewValue.newConfigList.length > 1
      ? addNewValue.newConfigList.pop()
      : ElMessage({
          message: '不能删除所有配置内容',
          type: 'error',
        })
  "
 >
   <template #reference>
    <el-button type="danger"> 删除最后一个表单配置内容 </el-button>
  </template>
</el-popconfirm>

jsx 形式中的 vue3 中,可以使用

import { defineComponent } from 'vue';
import { ElPopconfirm, ElButton } from 'element-plus';
export default defineComponent({
    render() {
        return <ElPopconfirm
            title="确认删除最后一个配置内容?"
            confirmButtonText="确认"
            cancelButtonText="取消"
            onConfirm={() => {
                addNewValue.newConfigList.length > 1
                  ? addNewValue.newConfigList.pop()
                  : ElMessage({
                      message: '不能删除所有配置内容',
                      type: 'error',
                    })
            }}
            v-slot={{
                reference: () => <ElButton type="danger">删除最后一个表单配置内容</ElButton>
            }}
        >
            
        </ElPopconfirm>
    }
});

其余相关的属性

其余相关的属性,比如 v-model 啥的,还是按照原来的写法去写。

这里需要注意一点 v-model 如果使用 jsx 写法,不会自动双向绑定,需要自己去写对应的函数。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解决vue项目 build之后资源文件找不到的问题

    解决静态资源失效的问题 这就需要修改我们的 config 中的 index.js了,默认的build 中的部分是这样的: build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublic

  • vue中ts无法识别引入的vue文件,提示找不到xxx.vue模块的解决

    目录 ts无法识别引入的vue文件,提示找不到xxx.vue模块 vite+ts引入 .vue或 .ts文件时提示找不到模块 一.先说第一个问题 二.引入自定义的ts文件时 ts无法识别引入的vue文件,提示找不到xxx.vue模块 在vue + ts项目中,在.ts中引入.vue文件,会提示打不到module,但是编译可能成功,运行也不报错 在src根目录下,新建一个sfc.d.ts文件这个里面的 declare module "*.vue" {     import Vue fro

  • vue3无法使用jsx的问题及解决

    目录 vue3无法使用jsx问题 报错一:无法使用 JSX,除非提供了 "--jsx" 标志 报错二:ElementPlusIconsVue挂载问题 关于vue3的jsx写法问题 安装 @vitejs/plugin-vue-jsx vite 插件 编写示例 vue3无法使用jsx问题 报错一:无法使用 JSX,除非提供了 "--jsx" 标志 在Vite+Vue3.0中使用jsx语法开发,需要安装jsx插件 npm i @vitejs/plugin-vue-jsx

  • mysql本地登录无法使用端口号登录的解决方法

    最近在使用linux上进行本地登录时,发现既然无法正常登录 , 报如下错误信息: [root@xxxx ~]# mysql -h localhost -u root -p -P 3306 Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 分析:使用mysql --verbose --help进行分析,才发现原来port和socke

  • Pycharm无法使用已经安装Selenium的解决方法

    电脑C盘安装python27的时候也安装了selenium,但是最近刚刚使用工具Pycharm,新建工程后,然后建立.py文件后,使用语句:from selenium.webdriver.support.wait import WebDriverWait 接着提示没有selenium这个模块,后来发现,在Pycharm上运行脚本时,使用的是其自带的虚拟环境,而不是电脑已经装配好的python27的环境: 该环境本身缺少很多外部库,尝试在此环境下装selenium,但是失败了: 所以,接下来只能P

  • 关于Flask项目无法使用公网IP访问的解决方式

    最近在折腾Python Web,在测试的时候发现,本机可以正常访问,但外网无法通过公网IP访问页面.经过各种搜索,有大致三种解决方案. 一.修改/添加安全组端口 这是第一种方案,也是能解决大部分问题的一个方案. 由于我的服务器是阿里云的,所以在阿里云的ECS云服务器控制台中,管理安全组,添加5000和8000端口以便测试. 经过测试,外网依旧无法访问.失败-- 二.配置/关闭防火墙 由于我的服务器是Windows Server 2016 操作系统,经过提醒,考虑是否是防火墙未允许端口通过. 如图

  • React报错之组件不能作为JSX组件使用的解决方法

    目录 总览 返回单个JSX元素 不要忘记返回值 更新React类型声明 总览 组件不能作为JSX组件使用,出现该错误有多个原因: 返回JSX元素数组,而不是单个元素. 从组件中返回JSX元素或者null以外的任何值. 使用过时的React类型声明. 返回单个JSX元素 下面是一个错误如何发生的示例. // App.tsx // ️ 'App' cannot be used as a JSX component. // Its return type 'Element[]' is not a va

  • Vite创建Vue3项目及Vue3使用jsx详解

    目录 Vite创建Vue3项目 1. 输入项目名称 2. 选择框架 3. 选择不同的vue 4. 项目创建完成 5. 项目结构 6. 启动项目 Vue3中使用jsx 1. 安装插件 2. 注册插件 3. 使用插件 注意 总结 Vite创建Vue3项目 Vite 需要 Node.js 版本 >= 12.0.0.(node -v 查看自己当前的node版本) 使用 yarn:yarn create @vitejs/app 使用 npm:npm init @vitejs/app 1. 输入项目名称 这

  • 关于Vue3父子组件emit参数传递问题(解决Vue2this.$emit无效问题)

    目录 1.解决this.$emit无效问题 2.Vuex问题 3.总结 之前写了一篇Vue3路由跳转问题的博客,发现还是有很多同学对基本的使用改变还没有了解,于是我就顺道把常用的组件间传递的方式也写一下吧....... 注意的是: 1.Vue3中不在强调this的使用,可以说你在setup中完全不能用this,不像Vue2中把全部的内容都集成到this中. 2.Vue3现在由于compositionAPI的方式可以说是弱化了Vuex的存在(当然Vuex现在可以用没什么变化). 3.如果您有Vue

  • element-plus 在vue3 中不生效的原因解决方法(element-plus引入)

    目录 1.安装element-plus (3种方式 ) 2. 在main.js种引用 原因一 原因二 vue3.0 不兼容 element-ui ,于是推出了element-plus 1.安装element-plus (3种方式 ) npm install element-plus --save (推荐)yarn add element-pluspnpm install element-plus 2. 在main.js种引用 import 'element-plus/theme-chalk/in

  • 图文详解Vue3没有代码提示问题的解决办法

    在上一篇笔记中提到了Vue3+vite+Ts写代码过程中,出现的代码自动补全失效功能,今天来谈谈如何解决这个问题. 首先,我们已经很明确的就是安装了volar插件之后,HTML标签片段补全已经失效,即在template中书写HTML标签时,不会再有代码补全,即输入“div”,就是“div”,而不再是“<div></div>”,为了解决这个问题,我们需要在不删除volar插件的同时,对Vscode做一些配置. 打开设置,进入到如下界面: 选择 文本编辑器 -> 文本 ->

  • 基于@Table注解无法使用及报红的解决

    目录 @Table注解无法使用及报红 @Table注解详解 spring @Table注解作用是 常用的两个属性 @Table注解无法使用及报红 在新建实体类时想直接序列化,遇到注解不起作用的问题,后来发现是少了一个依赖,真是无语. @Table(name = "tb_user") public class User implements Serializable {     private static final long serialVersionUID=1L;     @Id

随机推荐