?用Vue?Demi?構(gòu)建同時兼容Vue2與Vue3組件庫
前言:
Vue Demi 是一個很棒的包,具有很多潛力和實用性。我強烈建議在創(chuàng)建下一個 Vue 庫時使用它。
根據(jù)創(chuàng)建者 Anthony Fu
的說法,Vue Demi
是一個開發(fā)實用程序,它允許用戶為 Vue 2 和 Vue 3 編寫通用的 Vue 庫,而無需擔心用戶安裝的版本。
以前,要創(chuàng)建支持兩個目標版本的 Vue 庫,我們會使用不同的分支來分離對每個版本的支持。對于現(xiàn)有庫來說,這是一個很好的方法,因為它們的代碼庫通常更穩(wěn)定。
缺點是,你需要維護兩個代碼庫,這讓你的工作量翻倍。對于想要支持Vue的兩個目標版本的新Vue庫來說,我不推薦這種方法。實施兩次功能請求和錯誤修復根本就不理想。
這就是 Vue Demi 的用武之地。Vue Demi 通過為兩個目標版本提供通用支持來解決這個問題,這意味著您只需構(gòu)建一次即可獲得兩個目標版本的所有優(yōu)點,從而獲得兩全其美的優(yōu)勢。
在本文中,我們將了解 Vue Demi 是做什么的,它是如何工作的,以及如何開始構(gòu)建一個通用的 Vue 組件庫。
一、Vue Demi 中的額外 API
除了 Vue 已經(jīng)提供的 API 之外,Vue Demi 還引入了一些額外的 API 來幫助區(qū)分用戶的環(huán)境和執(zhí)行特定于版本的邏輯。讓我們仔細看看它們!
請注意:Vue Demi 還包括 Vue 中已經(jīng)存在的標準 API,例如 ref、onMounted 和 onUnmounted 等。
1.isVue2 and isVue3
在 Vue Demi 中,isvue2 和 isvue3 API 允許用戶在創(chuàng)建 Vue 庫時應用特定于版本的邏輯。
例如:
import { isVue2, isVue3 } from 'vue-demi'? if (isVue2) {? ? // Vue 2 only? } else {? ? // Vue 3 only? }
vue2
Vue Demi 提供了 vue2 API,它允許用戶訪問 Vue 2 的全局 API,如下所示:
import { Vue2 } from 'vue-demi'? // in Vue 3 `Vue2` will return undefined? if (Vue2) {? ? Vue2.config.devtools = true? } install()
在 Vue 2 中,Composition API
作為插件提供,在使用它之前需要安裝在 Vue 實例上:
import Vue from 'vue'? import VueCompositionAPI from '@vue/composition-api'? Vue.use(VueCompositionAPI)
Vue Demi 會嘗試自動安裝它,但是對于您想要確保插件安裝正確的情況,提供了 install() API 來幫助您。
它作為 Vue.use(VueCompositionAPI) 的安全版本公開:
import { install } from 'vue-demi'? install()
二、Vue Demi 入門
要開始使用 Vue Demi,您需要將其安裝到您的應用程序中。在本文中,我們將創(chuàng)建一個集成 Paystack 支付網(wǎng)關(guān)的 Vue 組件庫。
你可以像這樣安裝 Vue Demi:
// Npm? npm i vue-demi? // Yarn? yarn add vue-demi
您還需要添加 vue
和@vue/composition-api
作為庫的對等依賴項,以指定它應該支持的版本。
現(xiàn)在我們可以將 Vue Demi 導入我們的應用程序:
<script lang="ts">? import {defineComponent, PropType, h, isVue2} from "vue-demi"? export default defineComponent({ ? // ...? })? </script>
此處所示,我們可以使用已經(jīng)存在的標準 Vue API,例如 defineComponent、PropType 和 h。
現(xiàn)在我們已經(jīng)導入了Vue Demi,讓我們來添加我們的props。這些是用戶在使用組件庫時需要(或不需要,取決于你的口味)傳入的屬性。
<script lang="ts"> import {defineComponent, PropType, h, isVue2} from "vue-demi" // Basically this tells the metadata prop what kind of data is should accept interface MetaData { ? [key: string]: any } export default defineComponent({ ? props: { ? ? paystackKey: { ? ? ? type: String as PropType<string>, ? ? ? required: true, ? ? }, ? ? email: { ? ? ? type: String as PropType<string>, ? ? ? required: true, ? ? }, ? ? firstname: { ? ? ? type: String as PropType<string>, ? ? ? required: true, ? ? }, ? ? lastname: { ? ? ? type: String as PropType<string>, ? ? ? required: true, ? ? }, ? ? amount: { ? ? ? type: Number as PropType<number>, ? ? ? required: true, ? ? }, ? ? reference: { ? ? ? type: String as PropType<string>, ? ? ? required: true, ? ? }, ? ? channels: { ? ? ? type: Array as PropType<string[]>, ? ? ? default: () => ["card", "bank"], ? ? }, ? ? callback: { ? ? ? type: Function as PropType<(response: any) => void>, ? ? ? required: true, ? ? }, ? ? close: { ? ? ? type: Function as PropType<() => void>, ? ? ? required: true, ? ? }, ? ? metadata: { ? ? ? type: Object as PropType<MetaData>, ? ? ? default: () => {}, ? ? }, ? ? currency: { ? ? ? type: String as PropType<string>, ? ? ? default: "", ? ? }, ? ? plan: { ? ? ? type: String as PropType<string>, ? ? ? default: "", ? ? }, ? ? quantity: { ? ? ? type: String as PropType<string>, ? ? ? default: "", ? ? }, ? ? subaccount: { ? ? ? type: String as PropType<string>, ? ? ? default: "", ? ? }, ? ? splitCode: { ? ? ? type: String as PropType<string>, ? ? ? default: "", ? ? }, ? ? transactionCharge: { ? ? ? type: Number as PropType<number>, ? ? ? default: 0, ? ? }, ? ? bearer: { ? ? ? type: String as PropType<string>, ? ? ? default: "", ? ? }, ? } </script>
上面看到的屬性是使用 Paystack
的 Popup JS
所必需的。
Popup JS 提供了一種將 Paystack 集成到我們的網(wǎng)站并開始接收付款的簡單方法:
data() { ? ? return { ? ? ? scriptLoaded: false, ? ? } ? }, ? created() { ? ? this.loadScript() ? }, ? methods: { ? ? async loadScript(): Promise<void> { ? ? ? const scriptPromise = new Promise<boolean>((resolve) => { ? ? ? ? const script: any = document.createElement("script") ? ? ? ? script.defer = true ? ? ? ? script.src = "https://js.paystack.co/v1/inline.js" ? ? ? ? // Add script to document head ? ? ? ? document.getElementsByTagName("head")[0].appendChild(script) ? ? ? ? if (script.readyState) { ? ? ? ? ? // IE support ? ? ? ? ? script.onreadystatechange = () => { ? ? ? ? ? ? if (script.readyState === "complete") { ? ? ? ? ? ? ? script.onreadystatechange = null ? ? ? ? ? ? ? resolve(true) ? ? ? ? ? ? } ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? // Others ? ? ? ? ? script.onload = () => { ? ? ? ? ? ? resolve(true) ? ? ? ? ? } ? ? ? ? } ? ? ? }) ? ? ? this.scriptLoaded = await scriptPromise ? ? }, ? ? payWithPaystack(): void { ? ? ? if (this.scriptLoaded) { ? ? ? ? const paystackOptions = { ? ? ? ? ? key: this.paystackKey, ? ? ? ? ? email: this.email, ? ? ? ? ? firstname: this.firstname, ? ? ? ? ? lastname: this.lastname, ? ? ? ? ? channels: this.channels, ? ? ? ? ? amount: this.amount, ? ? ? ? ? ref: this.reference, ? ? ? ? ? callback: (response: any) => { ? ? ? ? ? ? this.callback(response) ? ? ? ? ? }, ? ? ? ? ? onClose: () => { ? ? ? ? ? ? this.close() ? ? ? ? ? }, ? ? ? ? ? metadata: this.metadata, ? ? ? ? ? currency: this.currency, ? ? ? ? ? plan: this.plan, ? ? ? ? ? quantity: this.quantity, ? ? ? ? ? subaccount: this.subaccount, ? ? ? ? ? split_code: this.splitCode, ? ? ? ? ? transaction_charge: this.transactionCharge, ? ? ? ? ? bearer: this.bearer, ? ? ? ? } ? ? ? ? const windowEl: any = window ? ? ? ? const handler = windowEl.PaystackPop.setup(paystackOptions) ? ? ? ? handler.openIframe() ? ? ? } ? ? }, ? },
scriptLoaded
狀態(tài)幫助我們知道是否添加了Paystack Popup JS
腳本,并且 loadScript 方法加載 Paystack Popup JS 腳本并將其添加到我們的文檔頭部。
payWithPaystack 方法用于在調(diào)用時使用 Paystack Popup JS 初始化交易:
render() { ? ? if (isVue2) { ? ? ? return h( ? ? ? ? "button", ? ? ? ? { ? ? ? ? ? staticClass: ["paystack-button"], ? ? ? ? ? style: [{display: "block"}], ? ? ? ? ? attrs: {type: "button"}, ? ? ? ? ? on: {click: this.payWithPaystack}, ? ? ? ? }, ? ? ? ? this.$slots.default ? this.$slots.default : "PROCEED TO PAYMENT" ? ? ? ) ? ? } ? ? return h( ? ? ? "button", ? ? ? { ? ? ? ? class: ["paystack-button"], ? ? ? ? style: [{display: "block"}], ? ? ? ? type: "button", ? ? ? ? onClick: this.payWithPaystack, ? ? ? }, ? ? ? this.$slots.default ? this.$slots.default() : "PROCEED TO PAYMENT" ? ? ) }
render
函數(shù)幫助我們創(chuàng)建沒有
標簽的組件,并返回一個虛擬 DOM 節(jié)點。
如果你注意到,我們在條件語句中使用了Vue Demi的一個API,isVue2,來有條件地渲染我們的按鈕。如果沒有這一點,如果我們想在Vue 2應用程序中使用我們的組件庫,我們可能會因為Vue 2不支持Vue 3的一些API而遇到錯誤。
現(xiàn)在,當我們構(gòu)建我們的庫時,它可以在 Vue 2 和 Vue 3 中訪問。
到此這篇關(guān)于用Vue Demi 構(gòu)建同時兼容Vue2與Vue3組件庫的文章就介紹到這了,更多相關(guān) 使用Vue Demi 構(gòu)建內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ElementUI中利用table表格自定義表頭Tooltip文字提示
這篇文章主要介紹了ElementUI中利用table表格自定義表頭Tooltip文字提示,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07vue實現(xiàn)的雙向數(shù)據(jù)綁定操作示例
這篇文章主要介紹了vue實現(xiàn)的雙向數(shù)據(jù)綁定操作,結(jié)合完整實例形式較為詳細的分析了vue.js進行數(shù)據(jù)雙向綁定操作的常見實現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2018-12-12el-tree樹組件懶加載(后端上千條數(shù)據(jù)前端進行處理)
本文主要介紹了el-tree樹組件懶加載(后端上千條數(shù)據(jù)前端進行處理),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-03-03vue使用html2canvas和jspdf將html轉(zhuǎn)成pdf
在前端開發(fā)中, html轉(zhuǎn)pdf是最常見的需求,下面這篇文章主要給大家介紹了關(guān)于vue如何使用html2canvas和jspdf將html轉(zhuǎn)成pdf的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-03-03vue項目頁面的打印和下載PDF加loading效果的實現(xiàn)(加水印)
這篇文章主要介紹了vue項目頁面的打印和下載PDF加loading效果的實現(xiàn)(加水印),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12vue+ElementUI實現(xiàn)訂單頁動態(tài)添加產(chǎn)品數(shù)據(jù)效果實例代碼
本篇文章主要介紹了vue+ElementUI實現(xiàn)訂單頁動態(tài)添加產(chǎn)品效果實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07登錄頁面的實現(xiàn)及跳轉(zhuǎn)代碼實例(vue-router)
在Vue.js中可以使用vue-router來實現(xiàn)前端路由,通過路由來跳轉(zhuǎn)頁面,這篇文章主要給大家介紹了關(guān)于登錄頁面的實現(xiàn)及跳轉(zhuǎn)(vue-router)的相關(guān)資料,需要的朋友可以參考下2023-12-12