【vue vapor jsx 未雨綢繆】

隨著vue3.6.0 alpha的發布,vapor mode進入正式版本只是時間上的問題,可以預見的是各個組件庫都將積極適配vapor,這篇文章主要側重vue中使用jsx而非SFC,所以不涉及template相關。目前vue官方也是提供了vue-jsx-vapor這個倉庫,處于v2.5.4-beta.1階段,而vue3發布以來使用jsx的插件為 @vitejs/plugin-vue-jsx,依賴的是vue官方倉庫的babel-plugin-jsx,不知道后面會不會直接用vapo jsx還是說兩種jsx開發方式并行,ant-deisgn-vue倉庫已經將適配vapor mode提上了日程,對于ant-design-vue這種全部由jsx構建的組件庫,感覺適配的工作量會很大,對于參與開源有興趣的朋友可以關注一下

// 獲得編譯器宏和指令的類型提示
vscode 中安裝 ts-macro 插件,項目中安裝 `@ts-macro/tsc` 來替代 `tsc` 進行類型檢查// package.json
{"scripts": {"typecheck": "tsmc --noEmit"// ...}
}

一、變化1:組件定義

// 原
export default defineComponent({name: 'xx',setup(props, { attrs, slots, emit, expose }) {return () => <Comp />}
})// vapor jsx
export default defineVaporComponent((props) => {const attrs = useAttrs()const slots = useSlots()const model = defineModel()defineExpose({...})return <Comp />
})
// 以及下面兩種形式
export default defineComponent(() => {// ...同上return <Comp />
})
export default () => {// ...同上return <Comp />
}

vue-jsx-vapor 支持 Virtual DOM 和 Vapor DOM 混合使用。將 interop 設置為 true 后,在 defineVaporComponent 中定義的 JSX 會被編譯為 Vapor DOM, 在 defineVaporComponent 外定義的 JSX 會被編譯為 Virtual DOM

// vite.config.ts
import { defineConfig } from 'vite'
import vueJsxVapor from 'vue-jsx-vapor/vite'export default defineConfig({plugins: [vueJsxVapor({interop: true,}),],
})

二、變化2:編譯器宏

  1. 前置條件:需要手動開啟marcos
// vite.config.ts
import { defineConfig } from 'vite'
import vueJsxVapor from 'vue-jsx-vapor/vite'
export default defineConfig({plugins: [vueJsxVapor({ macros: true })]
})// ts-macro.config.ts
import vueJsxVapor from 'vue-jsx-vapor/volar'
export default {plugins: [ vueJsxVapor({ macros: true })],
}
  1. defineModel
    手動擋和自動擋的區別,vapor中如果需要觸發外層事件這種,按照相關issue來看應該是不會做defineEmits宏,所以需要通過props拿到事件,如onChange?.(data),就相當于emit(‘change’, data)這種觸發形式了
// 假設
<comp v-model="data" />// 原export default defineComponent({emits: ['update:modelValue'],setup(props, { emit }) {emit('update:modelValue', xx)return ...}
})// vapor jsx, 與SFC使用一致
export default defineComponent(() => {const model = defineModel()model.value = xxreturn ...
})
  1. defineSlots
// 原
export default defineComponent({slots: Object as SlotsType<{default: any}>,setup(props, { slots }) {return () => (<div>{ slots.default?.() } </div>)}
})// vapor jsx,與SFC使用有一點差異
export default defineComponent(() => {const slots = defineSlots({default: () => <div>default</div>})return (<slots.default />)
})
  1. defineExpose
// 原
export default defineComponent({setup(props, { expose }) {expose({a: 'xx'})return ...}
})// vapor jsx, 與SFC使用一致
export default defineComponent(() => {defineExpose({a: 'xx'})return ...
})
  1. defineStyle
    這個比較厲害,支持 CSS 變量和 JS 變量綁定;支持在文件中定義多個樣式宏;支持多個 CSS 預處理器:cssscsssasslessstyluspostcss;在函數內部定義則scope選項默認為true;支持css-modules
defineStyle(`.red {color: red;}  
`)
defineStyle.css({...})
defineStyle.scss({...})
defineStyle.less({...})
defineStyle.stylus({...})// css-modules
const styles = defineStyle.scss(`.foo { color: blue;.bar { background: red;}}
`)<div class={styles.foo} />

三、變化3:內置指令

  1. v-if、v-else-if、v-else
    老版中簡單的條件可以用v-show,稍微復雜一點的可以用三元表達式,再稍微復雜點還可以三元表達式套娃
// 是的老版也提供了一些內置指令支持
export default defineComponent({setup() {return () => (<><div v-show={isVisible} />{// 或}{isStatus ? <CompA /> : <CompB />}</>)}
})// vapor jsx,使用與SFC基本一致
export default defineComponent(({ count = 0! }) => {return (<fieldset><legend>If</legend><div v-if={count === 0}>eq {count}</div><div v-else-if={count > 0}>lg {count}</div><div v-else>lt {count}</div></fieldset>)
})
  1. v-for
// 原
<div>
{ data.map((item, index) => {return (<div key={index}>{item}</div>)}) 
}
</div>// vapor jsx,與SFC使用基本一致
export default () => (<div v-for={(item, index) in 4} key={index}>{item}</div>
)
  1. v-slot、v-slots
// 原
export default defineComponent({slots: Object as SlotsType<{default: any}>,setup(props, { slots }) {// 取插槽傳遞的值return () => (<Child v-slots={{ default: (data) => <div>{data}</div> }>)/ 向子組件傳遞插槽return () => (<Child v-slots={slots}>)// 或者return () => (<Child v-slots={{ default: slots.default }>)// 或者return () => (<Child>{ slots.default?.() }</Child>)// 亦或者return () => (<Child><Comp /></Child>)}
})// vapor jsx,新增了v-slot,
export default defineComponent(({ count = 0! }) => {return (<>// 取插槽傳遞出的值<ChildA v-slot={{ foo }}>{{ foo }}</ChildA>// 向子組件傳遞插槽<ChildB v-slots={{ title: xx }} /></>)
})
  1. v-model
    babel-plugin-jsx還提供過v-models,但1.1.0版本過后不推薦使用,這里就不再提,vapor jsx也不支持v-models,這個指令兩個版本使用差別不大,vapor jsx拓展了動態屬性與修飾符的用法
// 原
<input v-model={val} />
<input v-model:argument={val} />
<input v-model={[val, ['modifier']]} />
// 或者
<input v-model_modifier={val} />
<A v-model={[val, 'argument', ['modifier']]} />
// 或者
<input v-model:argument_modifier={val} />// vapor jsx
<imput v-model={val} />
<input v-model:argument={val} />
// 動態參數,因為jsx不支持數組表達式,所以用$代替,即`$name$`這種形式
<input v-model:$name$={foo} /> // 等同于SFC <input v-model['name']="foo" />
// 修飾符,因為jsx不支持.關鍵字,所以用下劃線_代替
<input v-model_number={value} /> // 等同于SFC <input v-model.number="value" />

總結

vue之前的jsx的整體結構更偏向于options API,雖然在setup中用的都是composition API,這種算是承接了vue2到vue3的轉變,開發體驗也比較向react jsx的方向靠攏,新的vapor jsx則是減少了與 SFC 使用的割裂感,將編譯器宏、內置指令也帶到了jsx開發中,降低了上手難度,也許會吸引到更多的用戶來體驗在vue中使用jsx開發

特性JSX (babel-plugin-jsx)Vapor JSX (vue-jsx-vapor)
組件定義setup() 返回渲染函數直接返回JSX
編譯器宏不支持defineXxx 系列
指令支持僅基礎指令(v-show)常用指令(v-if/v-for等)
插槽系統v-slotsv-slotv-slots
樣式處理傳統CSS方案defineStyle

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93189.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93189.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93189.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

go語言數據結構與排序算法

package mainimport "fmt"func main() {Bubble_Sort()Select_Sort()Insert_Sort()Shell_Sort()Heap_Sort()Merge_Sort()Quick_Sort() }一、1、冒泡排序 // 冒泡排序 func Bubble_Sort() {str : []int{9, 1, 5, 8, 3, 7, 4, 6, 2}// 正向冒泡for i : 0; i < len(st…

Petalinux生成文件的關系

1. 生成文件概述BOOT.BIN是引導程序&#xff0c;包括了 u-boot.elf是build u-boot生成的zynq_fsbl.elf&#xff08;引導PS和PL的啟動&#xff09;elf文件是和啟動引導相關的文件image.ub是鏡像文件roofs.cpio.gz用來構建根文件系統

MongoDB的操作

在 Java 中操作 MongoDB 的 增刪改查&#xff08;CRUD&#xff09; 主要有兩種方式&#xff1a; Spring Data MongoDB&#xff08;推薦&#xff0c;類似 JPA 風格&#xff09;MongoDB Java Driver&#xff08;原生 API&#xff0c;更靈活&#xff09;1. Spring Data MongoDB 方…

getConnectionOwnerUid

在Android系統中&#xff0c;為了進行網絡權限控制、流量統計等&#xff0c;需要將網絡連接&#xff08;如Socket&#xff09;與發起該連接的應用UID關聯起來。這種關聯通常在內核中建立&#xff0c;并在用戶空間通過一些接口進行查詢。 1. 內核中的實現基礎 Linux內核中&#…

開源 Arkts 鴻蒙應用 開發(十)通訊--Http數據傳輸

文章的目的為了記錄使用Arkts 進行Harmony app 開發學習的經歷。本職為嵌入式軟件開發&#xff0c;公司安排開發app&#xff0c;臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 Arkts …

net8.0一鍵創建支持(RabbitMQ)

Necore項目生成器 - 在線創建Necore模板項目 | 一鍵下載 RabbitMQController.cs using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; using System.Threading.Tasks; using UnT.Tem…

Rust 泛型與特性

Rust 泛型與特性 引言 Rust 語言以其安全性和高效性在編程語言中獨樹一幟。Rust 的泛型和特性是其核心特性之一,它們使得開發者能夠編寫更加通用、靈活且安全的代碼。本文將深入探討 Rust 中的泛型和特性,包括其概念、用法以及在實際開發中的應用。 泛型簡介 概念 泛型是…

LangChain學習——結構化輸出和數據解析

LangChain 本指南全面介紹LangChain中結構化輸出生成和數據解析的核心功能&#xff0c;包括Pydantic BaseModel構造、各種輸出解析器的使用&#xff0c;以及高級錯誤處理機制。 詳細測試樣例和代碼可參考如下兩個鏈接&#xff1a; test_output_parserstest_pydantic_base_mo…

基于華為ENSP的BGP的狀態機深入淺出

本篇技術博文摘要 &#x1f31f; 本文章主要探討BGP狀態機如何控制BGP連接的建立與維護&#xff0c;以及BGP協議在運行過程中如何交換路由信息并確保網絡的穩定性 引言 &#x1f4d8; 在這個快速發展的技術時代&#xff0c;與時俱進是每個IT人的必修課。我是腎透側視攻城獅&…

Android 15中的16KB大頁有何優勢?

deepseek回答&#xff1a; Android 15引入的16KB大內存頁是系統性能優化的關鍵變革&#xff0c;其核心優勢體現在以下方面&#xff1a; ? 一、性能全面提升 系統整體加速 配置16KB頁面的設備整體性能提升5%-10%&#xff0c;通過減少內存管理開銷釋放更多資源用于應用運行。…

Gis數據的A*算法規劃航線

1.1 用到的技術棧geotools JTSJgrapht1.2 實現思路// 定義柵格網格參數private static final double CELL_SIZE_DEGREES 0.005;private static int gridWidth 0;//格子高度 index 1private static int gridHeight 0;//格子寬度// 1. 讀取GeoJSON文件File geoJsonFile new …

Spring Boot 默認使用 CGLIB,但CGLIB 無法代理 final 類或 final 方法

那么當這兩件事沖突時&#xff0c;Spring Boot 是怎么“解決”的呢&#xff1f;答案是&#xff1a;它不解決&#xff0c;也無法解決。當這種情況發生時&#xff0c;你的應用程序會直接啟動失敗。這不是 Spring Boot 的疏忽&#xff0c;而是由 CGLIB 的底層原理和 Java 語言的規…

cuda編程筆記(10)--memory access 優化

全局內存訪問優化&#xff08;Coalesced Access&#xff09; 什么是 Coalesced Access&#xff1f; 定義&#xff1a;一個 warp&#xff08;32 個線程&#xff09;在同一指令中訪問全局內存時&#xff0c;如果這些訪問請求可以合并成盡可能少的內存事務&#xff08;通常是 32…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第三十一課——車牌識別的FPGA實現(3)車牌字符分割預處理

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

電子電氣架構 --- 汽車軟件全生命周期

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

力扣面試150(41/150)

7.25 56. 合并區間 以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 intervals[i] [starti, endi] 。請你合并所有重疊的區間&#xff0c;并返回 一個不重疊的區間數組&#xff0c;該數組需恰好覆蓋輸入中的所有區間 。 我的思路&#xff1a; 左端點升序…

【隧道篇 / IPsec】(7.6) ? 01. 利用向導快速建立IPsec安全隧道 (點對點) ? FortiGate 防火墻

【簡介】相信很多人已經習慣利用導向快速創建VPN了&#xff0c;而且已經有部分嘗鮮者已經用上了FortiOS 7.6&#xff0c;但是會發現FortiOS 7.6下的VPN向導改變了很多&#xff0c;一時無法下手&#xff0c;下面我們來看看最常見的點對點是如何配置的。環境介紹在配置IPsec VPN之…

PLLIP核

。1 號紅色框內的速度等級代表著設備的速度 等級&#xff0c;保存默認就好&#xff1b;2 號紅色框內設置輸入頻率&#xff1b;3 號紅色框選擇 PLL 的工作模式。我們 開發板用的晶振是 50MHz 的&#xff0c;故在 2 號紅色框內我們填寫 50MHz&#xff1b;我們在 3 號紅色框內選正…

1.1 Deep learning?pytorch ?深度學習訓練出來的模型通常有效但無法解釋合理性? 如何 解釋?

DL 是什么&#xff0c;你如何理解DL模型&#xff1f; DL 對于我而言&#xff0c;就是人類試圖想通過數學語言描述人類學習過程的一門技術&#xff0c;或者說學科。 因此 DL 模型 相當于 數學 的 一個 funciton &#xff0c;有輸入&#xff0c;通過function處理&#xff0c;得…

java實現在工具類中注入其他對象方式

方案1&#xff1a; Slf4j Component public class ChatdocApiClient {Value("${chatdoc.app-id}")private String appId;Value("${chatdoc.secret}")private String secret;Value("${chatdoc.domain}")private String domain;private final Rest…