Migration from Backbone.Marionette to Vuejs
The creation of this approach was inspired by Martin Fowler and his article: StranglerFigApplication
If you have a component-based marionette application it is easy to organize migration to vue.
Only two things you need:
MnToVue.vue
- wrapper for marionette-based components, that allows you to use it as vue componentsVueToMn.js
- wrapper for vue components, that allows you to write new vue components, and attach it to oldVueToMn.js
): PageLayout.js(Marionette)
PageBlockLayout1(Marionette) <-- 3. Attach wrapped SimpleBlockElement.vue to old Layout
SimpleBlockElement(Marionette) <-- 1. Rewrite it to vue component: SimpleBlock1Element.vue
2. Use VueToMn and create wrapped SimpleBlockElement as MnLayout
PageBlockLayout2(Marionette)
SimpleBlockElement(Marionette) <--4. replace with previously created and wrapped SimpleBlockElement
MnToVue.vue
): PageLayout.js(Marionette) <-- 1. Rewrite it to vue component: PageLayout.vue
2. Register MnToVue as component(if it not registered as global component in App.vue).
3. Attach PageBlockLayout1 as MnComponent prop: mn-to-vue(:MnComponent="PageBlockLayout1")
PageBlockLayout1(Marionette)
SimpleBlock1Element(Marionette)
PageLayout.js(Marionette) <-- 4. Replace with PageLayout.vue
5. Attach PageBlockLayout1 as MnComponent prop: mn-to-vue(:MnComponent="PageBlockLayout1")
PageBlockLayout2(Marionette)
SimpleBlock2Element(Marionette)
You can register MnToVue.vue
in App.vue or any other vue-component, where you want to use wrapper:
Registration:
// In your App.vue or SomeNewCompnent.vue
...
components: {
MnToVue
}
...
Usage:
<mn-to-vue :MnComponent="YourOldMarionetteViewConstructor" :options="mnOptions"></mn-to-vue>
Because of options could be dynamically changed, MnToVue triggers service events every time as it happens,
For example:
const mnOptions = { a: 1, b: 2 };
// in case when `mnOptions.a` is changed it will be triggers `options:a:updated` event, it allows your OldMarionetteLayout
// to handle it somehow.
In this case at first, you should initialize wrapper with App.vue or Vue.
And after it you could use it to wrap you vue component into marionette layout.
Initialization:
//vue-to-mn.js
import App from '@/App.vue';
// or import Vue from 'vue';
import { wrapper } from './VueToMn.js';
const ReadyToUseWrapper = wrapper(App);
export { ReadyToUseWrapper };
Wrapping:
// wrapped-your-awesome-component.js
import { ReadyToUseWraper } from './vue-to-mn.js';
import YourAwesomeVueComponent from './your-awesome-component.vue';
export default YourAwesomeVueComponent = ReadyToUseWrapper(YourAwesomeVueComponent);
And after it, You can use wrapped-your-awesome-component.js
as ordinary Marionette.LayoutView component.
In case, when you need to handle some events from child’s vue component, you should instantiate YourAwesomeVueComponent
with extra option hoistEvents: string[]
, that should consist of events you want to hoist from child to parent.