Migrating Vue 3 to Vue 2 requires the option of using at least one library in Vue 3 and bootstrap-vue (Vue 2)?
P粉064448449
P粉064448449 2023-12-28 21:37:53
0
1
475

We are trying to update a library and the new version requires Vue 3 instead of Vue 2, namely tinymce-vue. Unfortunately, this is a company project using bootstrap-vue, which is not yet fully compatible with Vue 3 (bootstrap-vue3 is not yet production ready and we use some components that have not been migrated yet).

Migrating the complete application to Vue 3 is the main attempt. However, it doesn't allow using Bootstrap components in Vue 3, or if using compatibility mode, part of the app works, but the parts that require that component don't appear/work, or other parts of the component that require Vue 3 are broken. Is there any way to provide library-specific compatibility, or in this case, what is the recommended approach when two libraries require two different versions of Vue in the same component?

I'm not sure if this question should be asked differently, this is my first question in StackOverflow, so if I need to rephrase it or provide more details, please let me know.

P粉064448449
P粉064448449

reply all(1)
P粉046387133

The problem is that it is difficult or even impossible for Vue 2 and 3 applications to coexist in the same project because they depend on vue packages with the same name but different versions. Even it is possible to use vue package aliases with different names or use modular Vue (import Vue from 'vue') as a version and Vue CDN (window.Vue ) For another version in first-party code, another issue that needs to be addressed is that the Vue library needs to use a specific Vue version.

This requires building and bundling the sub-application using its preferred Vue version and library, which is very close to the concept of a micro-frontend application.

Suppose you have a Vue 3 sub-application that uses a Vue 3 specific library (tinymce-vue) and is specifically written to expose all public APIs to communicate with the outside world:

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 wrapper components act as a bridge between a Vue 3 sub-application and the rest of the Vue 2 application:

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();
  },
};

If the wrapper and sub-application require additional synchronization based on specific points, such as provide/inject, template references, etc., this needs to be implemented specifically. In this regard, it's no different from the Vue 3->Vue 2 adapter or adapters involving other frameworks (Angular, React).

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template