共计 4795 个字符,预计需要花费 12 分钟才能阅读完成。
在本文中,咱们通过思考其性能、工作原理以及如何开始应用它来理解 Vue Demi。
Vue Demi 是一个很棒的包,具备很多后劲和实用性。我强烈建议在创立下一个 Vue 库时应用它。
依据创建者 Anthony Fu 的说法,Vue Demi 是一个开发实用程序,它容许用户为 Vue 2 和 Vue 3 编写通用的 Vue 库,而无需放心用户装置的版本。
以前,要创立反对两个指标版本的 Vue 库,咱们会应用不同的分支来拆散对每个版本的反对。对于现有库来说,这是一个很好的办法,因为它们的代码库通常更稳固。
毛病是,你须要保护两个代码库,这让你的工作量翻倍。对于想要反对 Vue 的两个指标版本的新 Vue 库来说,我不举荐这种办法。施行两次性能申请和谬误修复基本就不现实。
这就是 Vue Demi 的用武之地。Vue Demi 通过为两个指标版本提供通用反对来解决这个问题,这意味着您只需构建一次即可取得两个指标版本的所有长处,从而取得两败俱伤的劣势。
在本文中,咱们将理解 Vue Demi 是做什么的,它是如何工作的,以及如何开始构建一个通用的 Vue 组件库。
Vue Demi 中的额定 API
除了 Vue 曾经提供的 API 之外,Vue Demi 还引入了一些额定的 API 来帮忙辨别用户的环境和执行特定于版本的逻辑。让咱们认真看看它们!
请留神,Vue Demi 还包含 Vue 中曾经存在的规范 API,例如 ref、onMounted 和 onUnmounted 等。
isVue2 and isVue3
在 Vue Demi 中,isvue2
和 isvue3
API 容许用户在创立 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,您须要将其装置到您的应用程序中。在本文中,咱们将创立一个集成 Paystack 领取网关的 Vue 组件库。
你能够像这样装置 Vue Demi:
// Npm
npm i vue-demi
// Yarn
yarn add vue-demi
您还须要增加 vue
和 @vue/composition-api
作为库的对等依赖项,以指定它应该反对的版本。
当初咱们能够将 Vue Demi 导入咱们的应用程序:
<script lang="ts">
import {defineComponent, PropType, h, isVue2} from "vue-demi"
export default defineComponent({// ...})
</script>
如此处所示,咱们能够应用曾经存在的规范 Vue API,例如 defineComponent
、PropType
和 h
。
当初咱们曾经导入了 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 集成到咱们的网站并开始接管付款的简略办法:
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
状态帮忙咱们晓得是否增加了 Paystack Popup JS 脚本,并且 loadScript
办法加载 Paystack Popup JS 脚本并将其增加到咱们的文档头部。
payWithPaystack
办法用于在调用时应用 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 函数帮忙咱们创立没有 <template>
标签的组件,并返回一个虚构 DOM 节点。
如果你留神到,咱们在条件语句中应用了 Vue Demi 的一个 API,isVue2
,来有条件地渲染咱们的按钮。如果没有这一点,如果咱们想在 Vue 2 应用程序中应用咱们的组件库,咱们可能会因为 Vue 2 不反对 Vue 3 的一些 API 而遇到谬误。
当初,当咱们构建咱们的库时,它能够在 Vue 2 和 Vue 3 中拜访。
残缺的源代码可在此处取得:https://github.com/ECJ222/vue-paystack2