我們正在嘗試更新一個函式庫,新版本需要 Vue 3 而不是 Vue 2,也就是tinymce-vue。不幸的是,這是一個使用 bootstrap-vue 的公司項目,尚未與 Vue 3 完全相容(bootstrap-vue3 尚未做好生產準備,我們使用了一些尚未遷移的元件)。
將完整的應用程式遷移到 Vue 3 是主要嘗試。但是,它不允許在 Vue 3 中使用 Bootstrap 元件,或者如果使用相容模式,應用程式的一部分可以工作,但需要該元件的部分不會出現/工作,或者元件的其他部分需要 Vue 3個壞了。有沒有什麼方法可以提供特定於庫的兼容性,或者在這種情況下,當需要兩個庫在同一組件中需要兩個不同版本的 Vue 時,建議的方法是什麼?
我不確定這個問題是否應該以不同的方式提出,這是我在 StackOverflow 中的第一個問題,所以如果我需要重新表述或提供更多詳細信息,請告訴我。
P粉0463871332023-12-29 15:53:24
問題在於,Vue 2 和 3 應用程式很難甚至不可能在同一個專案中共存,因為它們依賴同名但不同版本的 vue
套件。即使可以使用不同名稱的vue
套件別名或使用模組化Vue(import Vue from 'vue'
)作為一個版本和Vue CDN (window. Vue
)對於第一方程式碼中的另一個版本,另一個需要解決的問題是Vue函式庫需要使用特定的Vue版本。
這需要使用其首選的 Vue 版本和庫來建立和捆綁子應用程序,這與微前端應用程式的概念非常接近。
假設有一個 Vue 3 子應用程式使用 Vue 3 特定函式庫 (tinymce-vue),並專門編寫用於公開所有公共 API 以與外界通訊:
let MyV3Comp = { template: `<div>{{ myV3Prop }} {{ myV3Data }}</div`, props: ['myV3Prop'], emits: ['myV3Event'], setup(props, ctx) { const myV3Data = ref(1); const myV3Method = () => {}; ctx.emit('myV3Event', Math.random()); // Component public api needs to be exposed to be available on mount() instance ctx.expose({ myV3Data, myV3Method }); return { myV3Data, myV3Method } }, }; // Sub-app entry point let createMyV3App = initialProps => createApp(MyV3Comp, initialProps); export default createMyV3App;
Vue 2 包裝組件可作為 Vue 3 子應用程式和 Vue 2 應用程式其餘部分之間的橋樑:
import createMyV3App from '.../my-v3-app-bundled'; let MyV2WrapperComp = { template: `<div ref="v3AppWrapper"></div>`, props: ['myV2Prop'], emits: ['myV2Event'], data() { return { myV2Data: null }; }, methods: { // Sync wrapper events onMyV3Event(v) { this.$emit('myV2Event', v); } }, watch: { // Sync wrapper props and data myV2Data(v) { this.v3AppCompInstance.myV3Data.value = v; }, myV2Prop(v) { // Hacky! Better use data and methods from public api to pass info downwards this.v3AppCompInstance._instance.props.myV3Prop = v; }, }, mounted() { // Vue 3 automatically translates onMyV3Event prop as myV3Event event listener // Initial prop values make app props reactive // and allow to be changed through _instance.props this.v3App = createMyV3App({ onMyV3Event: this.onMyV3Event, myV3Prop: null }); // also available as undocumented this.v3App._instance.proxy this.v3AppCompInstance = this.v3App.mount(this.$refs.v3AppWrapper); // Sync wrapper data // Hacky! Better use event from public api to pass info upwards this.v3AppCompInstance._instance.proxy.$watch('myV3Data', v => this.myV2Data = v); }, unmounted() { this.v3App.unmount(); }, };
如果包裝器和子應用程式需要根據特定點進行額外同步,例如provide
/inject
、模板引用等,這個需要具體實作。在這一點上,它與 Vue 3->Vue 2 適配器或涉及其他框架(Angular、React)的適配器沒有什麼不同。