vue3無法使用jsx的問題及解決
vue3無法使用jsx問題
報錯一:無法使用 JSX,除非提供了 "--jsx" 標(biāo)志
在Vite+Vue3.0中使用jsx語法開發(fā),需要安裝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項目已經(jīng)全面支持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")”的參數(shù)不能賦給類型“Plugin_2”的參數(shù)。
解決辦法:
經(jīng)過善良的QQ群友點撥之后才明白....
需要遍歷掛載
報錯二:vue3.0+ts 找不到模塊“./XXX.vue”或其相應(yīng)的類型聲明。
鵝鵝鵝鵝鵝鵝.....還沒找到原因
卸載掉volar插件,全部報錯都消失
關(guān)于vue3的jsx寫法問題
安裝 @vitejs/plugin-vue-jsx vite 插件
yarn add @vitejs/plugin-vue-jsx -D npm install @vitejs/plugin-vue-jsx -D
安裝完成之后,在 vite.config.js 中進(jìn)行配置:
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 單文件組件。
編寫示例
基礎(chǔ)實例
vue3 新增了 setup 這個組合式 api,這樣就使得利用 jsx 編寫 vue 組件時的風(fēng)格非常類似于 react。在 setup 可以創(chuàng)建 state,接受 props,還可以直接返回 jsx。
import { defineComponent} from 'vue'; export default defineComponent({ ?? ?setup() { ?? ??? ?return <div>123456789</div> ?? ?} });
props 和 state
在 vue3 中,存在 ref 和 reactive 這兩個創(chuàng)建響應(yīng)式狀態(tài)的 api。由于內(nèi)置的觀察者模式,導(dǎo)致 vue 并不需要像 react 那樣,提供 useMemo,useCallback 等根據(jù)條件判斷是否更新的鉤子。
ref 在 render 函數(shù)中,會自動解構(gòu),不需要再使用 ref.value 來獲取里面的值。
推薦使用 ref,而不是 reactive。
props 則需要在 defineComponent 中使用 props 屬性,指定 props,該組件才會接受對應(yīng)的 props。
子組件不能在 setup 中返回 jsx,否則彈出警告,不渲染該子組件。
父組件接受子組件后,不可在 setup 中直接返回 ctx,或者 ctx.slots?.default?.() 計算后的值,第一種情況彈出警告,不渲染該子組件;第二種情況,該子組件不會響應(yīng)式。正確的做法,應(yīng)該是返回一個渲染函數(shù)。
子組件:
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?.() 計算后的值,這樣不能響應(yīng)式 ? ? ? ? // 同時,也要注意,不能直接返回 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> ? ? } })
事件監(jiān)聽
@vitejs/plugin-vue-jsx 該插件默認(rèn)將 @input 等相關(guān)模板語法,替換成了 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="確認(rèn)刪除最后一個配置內(nèi)容?" ? confirm-button-text="確認(rèn)" ? cancel-button-text="取消" ? @confirm=" ? ? ? addNewValue.newConfigList.length > 1 ? ? ? ? addNewValue.newConfigList.pop() ? ? ? : ElMessage({ ? ? ? ? ? message: '不能刪除所有配置內(nèi)容', ? ? ? ? ? type: 'error', ? ?? ? ?}) ? " ?> ? ?<template #reference> ? ? <el-button type="danger"> 刪除最后一個表單配置內(nèi)容 </el-button> ? </template> </el-popconfirm>
jsx 形式中的 vue3 中,可以使用
import { defineComponent } from 'vue'; import { ElPopconfirm, ElButton } from 'element-plus'; export default defineComponent({ ?? ?render() { ?? ??? ?return <ElPopconfirm ?? ??? ??? ?title="確認(rèn)刪除最后一個配置內(nèi)容?" ?? ??? ??? ?confirmButtonText="確認(rèn)" ?? ??? ??? ?cancelButtonText="取消" ?? ??? ??? ?onConfirm={() => { ?? ??? ??? ??? ?addNewValue.newConfigList.length > 1 ? ? ? ?? ??? ??? ?? addNewValue.newConfigList.pop() ? ? ? ?? ??? ??? ?: ElMessage({ ? ? ? ? ? ?? ??? ??? ?message: '不能刪除所有配置內(nèi)容', ? ? ? ? ? ?? ??? ??? ?type: 'error', ? ?? ? ??? ??? ??? ?}) ?? ??? ??? ?}} ?? ??? ??? ?v-slot={{ ?? ??? ??? ??? ?reference: () => <ElButton type="danger">刪除最后一個表單配置內(nèi)容</ElButton> ?? ??? ??? ?}} ?? ??? ?> ?? ??? ??? ? ?? ??? ?</ElPopconfirm> ?? ?} });
其余相關(guān)的屬性
其余相關(guān)的屬性,比如 v-model 啥的,還是按照原來的寫法去寫。
這里需要注意一點 v-model 如果使用 jsx 寫法,不會自動雙向綁定,需要自己去寫對應(yīng)的函數(shù)。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
element-plus中el-table點擊單行修改背景色方法
這篇文章主要給大家介紹了關(guān)于element-plus中el-table點擊單行修改背景色的相關(guān)資料,這是產(chǎn)品新加了的一個需求,分享給同樣遇到這個需求的朋友,需要的朋友可以參考下2023-07-07使用elementUI表單校驗函數(shù)validate需要注意的坑及解決
這篇文章主要介紹了使用elementUI表單校驗函數(shù)validate需要注意的坑及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06Vuex2.0+Vue2.0構(gòu)建備忘錄應(yīng)用實踐
這篇文章主要為大家詳細(xì)介紹了Vuex2.0+Vue2.0構(gòu)建備忘錄應(yīng)用實踐,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11vue.js 圖片上傳并預(yù)覽及圖片更換功能的實現(xiàn)代碼
這篇文章主要介紹了vue.js 圖片上傳并預(yù)覽及圖片更換功能,小編主要圍繞我們?nèi)粘J褂霉δ艿睦幼鲋v解,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08